【3D数学基础】猫都能听懂的旋转矩阵原理
时间过的真快,转眼就有四个多月没更新了。最近疫情严重哪都没去,天天宅在家里不是追剧就是看教程。这两天刚好重新温习了旋转矩阵。今天转念一想,干脆趁热写篇推文好了。既分享了知识同时也可以作为记录,不然时间久了后面又会忘记
废话不多说,直接切入主题
经常使用三维软件的小伙伴,看到下面这张图一定不会陌生:
没错这是Maya的旋转工具图标。我们知道三维空间的旋转工具通常需要控制三个不同方向的分量来实现物体任意方向的旋转。但是用归用,物体旋转的基本原理究竟是什么呢?科普时间到~
旋转矩阵
作为3D数学基础,旋转矩阵在三维制作软件及游戏引擎中的运用无处不在,但它究竟是什么东西呢?我们先看看百度百科中1997年江苏广播电视大学学报中的旋转矩阵概念:
旋转 矩阵(英语:RotationMatrix)是在乘以一个向量的时候有改变向量的方向但不改变大小的效果并保持了手性的矩阵。
简单来说,旋转矩阵是作用于向量的,目的就是在不改变向量大小的情况下旋转这个向量,就好比时钟的指针一样绕着中心旋转。而且旋转的空间只能在同一个手性的坐标系中。及左手坐标系的向量不能旋转成右手坐标系的向量。什么是手性呢,简单来说如下图所示,拿一面镜子照钟表,镜子内部反射的钟表表盘和外部的钟表表盘就是两个手性的坐标系。
当然旋转向量的方法不止旋转矩阵一种,常见的还有四元数。但作为今天讨论的主题,我们在此只讲旋转矩阵。
同时为了循序渐进更好理解,在讲三维旋转矩阵之前,我们先看看更低维度的旋转矩阵,也就是二维旋转矩阵。维度少理解起来也更直观,后续我们再将低维度的结果推广到更高维度。
二维旋转矩阵
1. 使用基础向量表示任意向量
这里我们拿出最熟悉的笛卡尔坐标系作为参考,可以看到下图中 x 轴上有一点 M(1 , 0),y 轴上有一点 U(0 , 1),两个点和原点 O 分别形成两条单位向量 m 和 u 。
这时,我们就可以用这两条向量 m 和 u 表示坐标系中所有的向量。
比如向量 Q(k , l) 可以表示成 km+lu ①,向量 H(12.2 , 34.5) 可以表示成 12.2m+34.5u
2. 将任意向量的旋转分解成基础向量的旋转
由于向量的矩阵变换属于线性变换, 所以我们旋转这个坐标轴中的任意向量可以等价于旋转相同空间数轴上的标准单位向量。求出旋转后的结果,代入上述等式①中(km+lu),得到旋转后的目标向量。
3. 二维平面中任意向量绕原点旋转的公式
下面我们就一步步推导出变化后的向量是多少:
对于数学推导而言,一般会从最具体实际出发,推导出更抽象的一般定理。这里我们也可以使用相同的思路。
比如我们要将下图中位于 x 轴上的单位向量 u 沿原点 O 旋转 θ 度到单位向量 v 。
我们可以很简单的用三角函数算出旋转后的向量 v。
同理我们也很容易得出位于 y 轴上的单位向量 p 沿原点 O 旋转 θ 度的单位向量 q。
因为上面两个向量是在 x 轴和 y 轴上的单位向量,所以我们得出二维平面直角坐标系中任意一向量绕原点旋转后 θ 度的目标向量是:
4. 将上述原理转换成旋转矩阵
通过上面的推演我们得到了最终的结果,但是为了更加方便运用拓展,我们这里要将整个变换抽离出来变成旋转矩阵。可以看到 x 项的系数是 cosθ 和 sinθ ,y 项的系数是 -sinθ 和 cosθ,所以得到矩阵应该是这样的(分左乘和右乘两种情况,计算结果是一样的)(i 和 j 是需要变换的二维向量坐标):
(左乘)
(右乘)
这时我们将这个矩阵放入虚幻中测试一下,在材质中控制WorldPosition旋转模型,这里只输入 x 和 y 两个轴向(相当于在二维空间中旋转),保持z轴不变,可以看到下图最终结果是完全正确的!说明这个矩阵结果没有问题 (有一点变黑是因为没有做法线方向随着顶点的偏移重新计算,所以会导致光照效果的不对 )
这里贴上代码:
float2x2rotator = float2x2 (
cos(a) ,sin(a),
-sin(a) ,cos(a)
);
float1x2vec =float1x2(
pos.x , pos.y
);
returnmul(vec , rotator);
大功告成,接下来我们只需要将二维的结果推导至三维,得到三维的旋转矩阵即可。
三维旋转矩阵
还记得文章开始的那个旋转图标吗,他有三个不同的轴向,除了用 x y z 来区分以外,这三个轴向有更加专业的名字,叫 Roll、Yaw 和 Pitch。在UE4中,Roll 对应指向前方的 X 轴,Yaw 对应 Y 轴,Pitch 指向上方的 Z 轴。
当我们调整这三个参数时,物体会保持所调整的轴向方向不变,同时绕着当前调整的轴向做旋转运动。因此我们可以将这三个轴的旋转分开来看,这样绕每个轴的旋转都可以看成是二维空间的旋转。
因此我们可以得出:
向量 v 围绕 x 轴 roll 旋转 θ 度的结果 Vx1(y 轴为二维平面的 x 轴,z 轴为二维平面的 y轴):
向量 v 围绕 y 轴 pitch 旋转 θ 度的结果 Vy1(x 轴为二维平面的 x 轴,z 轴为二维平面的 y轴):
向量 v 围绕 z 轴 yaw 旋转 θ 度的结果 Vz1(x 轴为二维平面的 x 轴,y 轴为二维平面的 y轴):
和推导二维旋转矩阵一样,我们需要将这个结果写成矩阵形式,在保证结果一致的情况下,也要考虑左乘和右乘的区别。最后的矩阵如下图所示,就是我们最熟悉的三维旋转矩阵了(这里是基于ue4坐标系的推导结果,不同坐标系的旋转矩阵不一样):
同样,我们在ue4的材质中用上述旋转矩阵控制世界位置偏移,结果也是正确的:
沿x轴旋转
沿y轴旋转
沿z轴旋转
具体的代码不发了,和上面2D旋转矩阵的代码差不多。
如果要同时旋转几个轴向,可以依次将要旋转的轴向旋转矩阵左乘或右乘应用在向量上,不过要注意左乘的顺序,如果顺序不对,就算旋转数值一样,最终的方向也会不一样。
到这里旋转矩阵的基础就讲完啦,是不是瞬间简单清晰了很多。
欢迎收藏关注转发点在看~ 返回搜狐,查看更多
责任编辑: