图形学基础:二维三维刚体的移动、缩放和旋转矩阵

news2024/11/26 16:49:02

一、二维

1.1 缩放矩阵

在这里插入图片描述

x,y分别表示在x轴,y轴缩放的倍数

示例: 点(2,1)在x,y轴上分别缩放x倍,y倍

在这里插入图片描述

1.2 平移矩阵

在这里插入图片描述

x,y分表表示在x轴,y轴上移动的距离

示例:点(2,1)分别在x轴,y轴上平移x距离,y距离
在这里插入图片描述

1.3 旋转矩阵

在这里插入图片描述
示例:点(x,y) 绕原点逆时针旋转θ°
在这里插入图片描述

示例:
点 (2,0) 绕原点旋转90°
在这里插入图片描述

绕任一点旋转?
转为先平移到这个点, 再旋转即可。

1.4 变换顺序

先平移再旋转,得到的变换矩阵是:
在这里插入图片描述
示例:

(2,0) 先平移 (0,2) 再旋转90°应该为: (-2,2)
在这里插入图片描述

如果换成是先旋转再平移则是(0,4):
在这里插入图片描述

二、三维

2.1 缩放矩阵

在这里插入图片描述

x,y,z分别表示点在x,y,z轴缩放的倍数

示例:
点 (2,1,2) 在x,y,z轴上分别缩放x,y,z倍
在这里插入图片描述

2.2 平移矩阵

在这里插入图片描述

示例:
点(2,1,2) 在x,y,z轴上分别移动 x,y,z距离
在这里插入图片描述

2.3 旋转矩阵

在这里插入图片描述

θ 表示点绕过原点的 x, y, z 轴旋转θ°
注意:绕某轴旋转则眼睛看向某轴的负方向,逆时针为正,顺时针为负(和左右手坐标系没关系)。

参考: https://zhuanlan.zhihu.com/p/147282442

示例:

  • 点(2,1,2) 绕过原点的y轴旋转90°,应为:(2, 1, -2)

在这里插入图片描述
在这里插入图片描述

  • 点(1,2,2) 绕过原点的x轴旋转90°,应为:(1,-2,2)
    在这里插入图片描述
  • 点(2,2,1) 绕过原点的z轴旋转90°,应为(-2,2,1)
    在这里插入图片描述

绕任一点旋转?
转为先平移到这个点, 再旋转即可。

2.4 变换顺序(同二维,不再赘述)

三、threejs中的矩阵变换 (Matrix3)

3.1 矩阵存储格式

如果将矩阵的元素存储为数组的话,我们人类易读的是行优先,但three.js采用的是列优先,它们区别如下:
在这里插入图片描述
不过,虽然three.js内部存储是列优先,但在传参时遵循的是行优先,看下面源码:

在这里插入图片描述

3.2 旋转方向的奇怪问题

three.js中使用矩阵旋转的时候有个奇怪的地方,如下:

  • new THREE.Matrix3().makeRotation(Math.PI/2):从0创建一个旋转矩阵,逆时针旋转90°;
  • new THREE.Matrix3().rotate(Math.PI/2):累加旋转, 顺时针旋转90°;

下面是例子:

<script type="module">
	import * as THREE from 'three';
	//makeRotation: 逆时针为正
	var m2 = new THREE.Matrix3().makeRotation(Math.PI/2);
	var ret2 = new THREE.Vector2(2,0).applyMatrix3(m2);
	//输出: (2,0) makeRotation(90°): {"x":1.2246467991473532e-16,"y":2}
	console.log(`(2,0) makeRotation(90°): ${JSON.stringify(ret2)}`)	
	
	//rotate是累加: 顺时针为正
	var m = new THREE.Matrix3().rotate(Math.PI/2);
	var ret = new THREE.Vector2(2,0).applyMatrix3(m);
	//输出: (2,0) rotate(90°): {"x":1.2246467991473532e-16,"y":-2}
	console.log(`(2,0) rotate(90°): ${JSON.stringify(ret)}`)
</script>

3.3 其他示例

<script type="module">
	import * as THREE from 'three';
	//先平移后逆时针旋转
	var m = new THREE.Matrix3().translate(0,2).rotate(-Math.PI/2);
	var ret = new THREE.Vector2(2,0).applyMatrix3(m);
	//(2,0) 先平移(0,2)后逆时针旋转90°: {"x":-1.9999999999999998,"y":2}
	console.log(`(2,0) 先平移(0,2)后逆时针旋转90°: ${JSON.stringify(ret)}`)
	
	//先逆时针旋转后平移
	var m2 = new THREE.Matrix3().rotate(-Math.PI/2).translate(0,2);
	var ret2 = new THREE.Vector2(2,0).applyMatrix3(m2);
	//(2,0) 先逆时针旋转90°后平移(0,2): {"x":1.2246467991473532e-16,"y":4}
	console.log(`(2,0) 先逆时针旋转90°后平移(0,2): ${JSON.stringify(ret2)}`)
</script>

四、c#中的矩阵 (Matrix3x2)

查看的c#矩阵源码地址:《Matrix3x2.Impl.cs》

4.1 矩阵存储格式

没有存储9个矩阵元素,而是6个,如:
在这里插入图片描述
内部存储是用了三个 Vector2 向量存储,参考源码:
在这里插入图片描述

4.2 奇怪的相乘顺序

一般认为的:
在这里插入图片描述

但实际上,c#是右乘,如:

//(2,0) 先逆时针旋转90°, 再平移 (0,2)
var m = Matrix3x2.CreateRotation(MathF.PI / 2) * Matrix3x2.CreateTranslation(0, 2);
//输出 (0,4)
Console.WriteLine(Vector2.Transform(new Vector2(2, 0), m));

但,,,好像结果是对的。。。这就牵扯到另外一个问题:

4.3 奇怪的矩阵转置

一般认为,平移矩阵是:
在这里插入图片描述
但c#构造后是:
在这里插入图片描述
参考源码:
在这里插入图片描述

一般认为,构造旋转矩阵是:
在这里插入图片描述
但c#构造后是:
在这里插入图片描述
参考源码:
在这里插入图片描述

但,恰好是 转置的矩阵右乘 刚好和我们认为的(非转置矩阵左乘)效果一致。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1587647.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

每日OJ题_BFS解决FloodFill④_力扣130. 被围绕的区域

目录 力扣130. 被围绕的区域 解析代码 力扣130. 被围绕的区域 130. 被围绕的区域 难度 中等 给你一个 m x n 的矩阵 board &#xff0c;由若干字符 X 和 O &#xff0c;找到所有被 X 围绕的区域&#xff0c;并将这些区域里所有的 O 用 X 填充。 示例 1&#xff1a; 输入&…

【MySQL】数据库节点的平滑扩容方案

一、背景 众所周知&#xff0c;数据库很容易成为应用系统的瓶颈。单机数据库的资源和处理能力有限&#xff0c;在高并发的分布式系统中&#xff0c;可采用分库分表突破单机局限。本文来探讨下数据库节点的平滑扩容方案 二、节点扩容 2.1、什么是节点扩容 扩容一般是指水平分…

test4122

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

Matlab 实时读取串口并绘图

Matlab 实时读取串口并绘图 Vofa Vofa 是一个很好的跨平台上位机软件&#xff0c;但是它无法保存数据&#xff0c;而且作者也并没有要继续更新的意思&#xff0c;保存数据功能应该是遥遥无期了。因此本文使用 Matlab 实时读取串口数据&#xff0c;并使用 plot 函数绘制。 vo…

【vscode】在本地加载远端环境并开发

【vscode】在本地利用远程服务器显卡跑代码 写在最前面vscode&#xff1a;远程到本地1、安装ssh插件2、添加服务器连接配置3、连接服务器4. SSH配置5. 在ssh中安装python解释器 vscode基本操作 &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 2024每日百字篆刻时光…

Grafana告警(邮件)自定义模板配置

一年前给客户部署配置过grafana&#xff0c;告警配置也是用的原始的&#xff0c;客户在使用过程中只需要一些核心点信息&#xff0c;想要实现这个就需要用Grafana的自定义告警模板以及编辑邮件模板。 通知模板 模板信息的配置中查阅了相关资料&#xff0c;自己组装了一套&…

Android Framework学习笔记(3)----Binder

什么是Binder&#xff1f; Binder是linux IPC机制的其中一种。它贯穿于应用层&#xff0c;framework层&#xff0c;以及linux Core层。 什么是IPC? 跨进程通信&#xff0c; InterProcess Communication. IPC机制都有哪些&#xff1f; 通道信号量消息队列BinderSocket共享内…

(Java)数据结构——排序(第一节)堆排序+PTA L2-012 关于堆的判断

前言 本博客是博主用于复习数据结构以及算法的博客&#xff0c;如果疏忽出现错误&#xff0c;还望各位指正。 堆排序&#xff08;Heap Sort&#xff09;概念 堆排序是一种基于堆数据结构的排序算法&#xff0c;其核心思想是将待排序的序列构建成一个最大堆&#xff08;或最小…

【C语言基础】:文件操作详解(后篇)

文章目录 一、文件的顺序读写1.1 顺序函数读写函数介绍1.2 fgetc函数和fputc函数1.3 fputs函数和fgets函数1.4 fprintf函数和fscanf函数1.5 fwrite函数和fread函数 二、文件的随机读写2.1 fseek函数2.2 ftell函数2.3 rewind函数 三、文件读取结束的判定3.1 feof函数 四、文件缓…

Linux操作系统的学习

Linux系统的目录结构 / 是所有目录的顶点目录结构像一颗倒挂的树 Linux常用命令 常见命令 序号命令对应英文作用1lslist查看当前目录下的内容2pwdprint work directory查看当前所在目录3cd [目录名]change directory切换目录4touch [文件名]touch如果文件不存在&#xff0c;新…

4. 依赖查找依赖注入

本小节源码&#xff1a;Spring-DI 1. 依赖查找 前面两个小节我们学习了如何将 Bean 对象分别以配置文件与注解的方式存入 Spring 中&#xff0c;然而通过 Bean 从 Spring 容器中取出的过程其实就是依赖查找&#xff0c;这里我简单归纳一下各种依赖查找的方式。 1.1 通过beanI…

【MySQL】索引篇

SueWakeup 个人主页&#xff1a;SueWakeup 系列专栏&#xff1a;学习技术栈 个性签名&#xff1a;保留赤子之心也许是种幸运吧 本文封面由 凯楠&#x1f4f8;友情提供 目录 本系列传送门 1. 什么是索引 2. 索引的特性 3. 索引的分类 4. 索引的优点及缺点 优点 缺点 5.…

FPGA基于VCU的H265视频压缩,HDMI2.0输入,支持4K60帧,提供工程源码+开发板+技术支持

目录 1、前言免责声明 2、相关方案推荐我这里已有的视频图像编解码方案 3、详细设计方案设计框图FPGA开发板视频输入Video PHY ControllerHDMI 1.4/2.0 Receiver SubsystemVideo Processing SubsystemVideo Frame Buffer WriteZynq UltraScale VCUPetaLinux 系统制作VLC播放器工…

ElasticSearch的数据同步【Java实现】

文章目录 1、思路分析1.1、同步调用1.2、异步通知1.3、监听binlog1.4、如何选择 2、实现数据同步2.1、思路2.2、demo2.3、声明交换机、队列1&#xff09;引入依赖2&#xff09;声明队列交换机名称3&#xff09;声明队列交换机 2.4、发送MQ消息2.5、接收MQ消息 3、代码链接分享 …

Quartz + SpringBoot 实现分布式定时任务

文章目录 前言一、分布式定时任务解决方案二、Quartz是什么&#xff1f;1.quartz简介2.quartz的优缺点 二、Quartz分布式部署总结 前言 因为应用升级&#xff0c;由之前的单节点微服务应用升级为集群微服务应用&#xff0c;所以之前的定时任务Spring Scheduled不再适用了&…

蓝桥备赛——组合数、其他技巧

对字符串进行permutations排列组合 from itertools import permutations a abc #对字符串进行permutations排列组合 for i in permutations(a,3):x .join(i)print (x,end ) print (\n------------------------------------) permutations后面的参数&#xff0c;第一个表示…

Canal 扩展篇

1.Canal介绍 GitHub - alibaba/canal: 阿里巴巴 MySQL binlog 增量订阅&消费组件 Canal 主要用途是基于 MySQL 数据库增量日志解析&#xff0c;提供增量数据订阅和消费&#xff0c;工作原理如下&#xff1a; Canal 模拟 MySQL slave 的交互协议&#xff0c;伪装自己为 M…

【原创】springboot+mysql宠物管理系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

Redis(二十)五大经典类型源码

文章目录 面试题源码核心Redis基本的数据结构(骨架)Redis数据库的实现Redis服务端和客户端实现其他 K-V实现怎样实现键值对(key-value)数据库的传统五大基本数据类型和新五大数据类型 5大数据结构底层C语言源码分析示例redisObject五大数据结构解析定义Debug Object keyString …

01 SQL基础 -- 初识数据库与安装

一、初识数据库 数据库是将大量数据保存起来,通过计算机加工而成的可以进行高效访问的数据集合。该数据集合称为数据库(Database, DB)。用来管理数据库的计算机系统称为数据库管理系统(Database Management System, DBMS) 1.1 DBMS 的种类 DBMS 主要通过数据的保存格式…