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

一、二维

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#构造后是:
在这里插入图片描述
参考源码:
在这里插入图片描述

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

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在MATLAB中,可以使用旋转矩阵来实现三维空间的刚体运动。旋转矩阵是一种正交矩阵,它可以保持长度、角度、面积等特征不变的仿射变换,即内积和度量不变。旋转矩阵的逆等于它的转置,同时行列式的值为正负1。 在MATLAB中,可以使用makehgtform函数来创建旋转矩阵。例如,如果给定一个单位向量normal和旋转角度theta,可以使用下面的代码创建旋转矩阵Matrix_Rot: theta=acos(costheta); Matrix_Rot=makehgtform('axisrotate',normal,theta); 其中,normal是旋转轴的单位向量,theta是旋转角度。这样,Matrix_Rot就是表示刚体运动的旋转矩阵。 更多关于旋转矩阵的信息,可以参考维基百科的页面和博客文章。关于MATLAB中的刚体运动和旋转矩阵的应用,还可以参考博客文章。 总结起来,MATLAB中的三维空间刚体运动可以通过旋转矩阵来实现,旋转矩阵是一种正交矩阵,它可以保持长度、角度、面积等特征不变的仿射变换。在MATLAB中,可以使用makehgtform函数来创建旋转矩阵。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [3D视觉(三)刚体运动及matlab实现](https://blog.csdn.net/piaoxuezhong/article/details/78524498)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jackletter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值