旋转变换(一)旋转矩阵

1. 简介

计算机图形学中的应用非常广泛的变换是一种称为仿射变换的特殊变换,在仿射变换中的基本变换包括平移、旋转、缩放、剪切这几种。本文以及接下来的几篇文章重点介绍一下关于旋转的变换,包括二维旋转变换、三维旋转变换以及它的一些表达方式(旋转矩阵、四元数、欧拉角等)。

2. 绕原点二维旋转

首先要明确旋转在二维中是绕着某一个点进行旋转,三维中是绕着某一个轴进行旋转。二维旋转中最简单的场景是绕着坐标原点进行的旋转,如下图所示:

2DRotation

如图所示点v 绕 原点旋转θθ 角,得到点v’,假设 v点的坐标是(x, y) ,那么可以推导得到 v’点的坐标(x’, y’)(设原点到v的距离是r,原点到v点的向量与x轴的夹角是ϕϕ ) 
x=rcosϕy=rsinϕx=rcosϕy=rsinϕ 
x=rcos(θ+ϕ)y=rsin(θ+ϕ)x′=rcos(θ+ϕ)y′=rsin(θ+ϕ) 
通过三角函数展开得到 
x=rcosθcosϕrsinθsinϕx′=rcosθcosϕ−rsinθsinϕ 
y=rsinθcosϕ+rcosθsinϕy′=rsinθcosϕ+rcosθsinϕ 
带入x和y表达式得到 
x=xcosθysinθx′=xcosθ−ysinθ 
y=xsinθ+ycosθy′=xsinθ+ycosθ 
写成矩阵的形式是: 

[xy]=[cosθsinθsinθcosθ][xy][x′y′]=[cosθ−sinθsinθcosθ]∗[xy]


尽管图示中仅仅表示的是旋转一个锐角θθ的情形,但是我们推导中使用的是三角函数的基本定义来计算坐标的,因此当旋转的角度是任意角度(例如大于180度,导致v’点进入到第四象限)结论仍然是成立的。

 

3. 绕任意点的二维旋转

绕原点的旋转是二维旋转最基本的情况,当我们需要进行绕任意点旋转时,我们可以把这种情况转换到绕原点的旋转,思路如下: 
1. 首先将旋转点移动到原点处 
2. 执行如2所描述的绕原点的旋转 
3. 再将旋转点移回到原来的位置

2DArbitraryRotate

也就是说在处理绕任意点旋转的情况下需要执行两次平移的操作。假设平移的矩阵是T(x,y),也就是说我们需要得到的坐标 v’=T(x,y)*R*T(-x,-y)(我们使用的是列坐标描述点的坐标,因此是左乘,首先执行T(-x,-y))

在计算机图形学中,为了统一将平移、旋转、缩放等用矩阵表示,需要引入齐次坐标。(假设使用2x2的矩阵,是没有办法描述平移操作的,只有引入3x3矩阵形式,才能统一描述二维中的平移、旋转、缩放操作。同理必须使用4x4的矩阵才能统一描述三维的变换)。

对于二维平移,如下图所示,P点经过x和y方向的平移到P’点,可以得到:

2DTranslate

x=x+txy=y+tyx′=x+txy′=y+ty 
由于引入了齐次坐标,在描述二维坐标的时候,使用(x,y,w)的方式(一般w=1),于是可以写成下面矩阵的形式

 

⎡⎣⎢xy1⎤⎦⎥=⎡⎣⎢100010txty1⎤⎦⎥⎡⎣⎢xy1⎤⎦⎥[x′y′1]=[10tx01ty001]∗[xy1]


按矩阵乘法展开,正好得到上面的表达式。也就是说平移矩阵是 

⎡⎣⎢100010txty1⎤⎦⎥[10tx01ty001]


如果平移值是(-tx,-ty)那么很明显平移矩阵式 

⎡⎣⎢100010txty1⎤⎦⎥[10−tx01−ty001]


我们可以把2中描述的旋转矩阵也扩展到3x3的方式,变为: 

⎡⎣⎢xy1⎤⎦⎥=⎡⎣⎢cosθsinθ0sinθcosθ0001⎤⎦⎥⎡⎣⎢xy1⎤⎦⎥[x′y′1]=[cosθ−sinθ0sinθcosθ0001]∗[xy1]


从平移和旋转的矩阵可以看出,3x3矩阵的前2x2部分是和旋转相关的,第三列与平移相关。有了上面的基础之后,我们很容易得出二维中绕任意点旋转的旋转矩阵了,只需要把三个矩阵乘起来即可:

 

 

M=⎡⎣⎢100010txty1⎤⎦⎥⎡⎣⎢cosθsinθ0sinθcosθ0001⎤⎦⎥⎡⎣⎢100010txty1⎤⎦⎥=⎡⎣⎢cosθsinθ0sinθcosθ0(1cosθ)tx+tysinθ(1cosθ)tytxsinθ1⎤⎦⎥M=[10tx01ty001]∗[cosθ−sinθ0sinθcosθ0001]∗[10−tx01−ty001]=[cosθ−sinθ(1−cosθ)tx+ty∗sinθsinθcosθ(1−cosθ)ty−tx∗sinθ001]

 

4. 三维基本旋转

我们可以把一个旋转转换为绕基本坐标轴的旋转,因此有必要讨论一下绕三个坐标值x、y、z的旋转。 
本文在讨论过程中使用的是类似于OpenGL中定义的右手坐标系,同时旋转角度的正负也遵循右手坐标系的约定。如下图所示

RightHanderRule

4.1 绕X轴的旋转

在三维场景中,当一个点P(x,y,z)绕x轴旋转θθ角得到点P’(x’,y’,z’)。由于是绕x轴进行的旋转,因此x坐标保持不变,y和z组成的yoz(o是坐标原点)平面上进行的是一个二维的旋转,可以参考上图(y轴类似于二维旋转中的x轴,z轴类似于二维旋转中的y轴),于是有: 
x=xx′=x 
y=ycosθzsinθy′=ycosθ−zsinθ 
z=ysinθ+zcosθz′=ysinθ+zcosθ 
写成(4x4)矩阵的形式 

⎡⎣⎢⎢⎢xyz1⎤⎦⎥⎥⎥=⎡⎣⎢⎢⎢10000cosθsinθ00sinθcosθ00001⎤⎦⎥⎥⎥⎡⎣⎢⎢⎢xyz1⎤⎦⎥⎥⎥[x′y′z′1]=[10000cosθ−sinθ00sinθcosθ00001]∗[xyz1]

 

4.2 绕Y轴旋转

绕Y轴的旋转和绕X轴的旋转类似,Y坐标保持不变,除Y轴之外,ZOX组成的平面进行一次二维的旋转(Z轴类似于二维旋转的X轴,X轴类似于二维旋转中的Y轴,注意这里是ZOX,而不是XOZ,观察上图中右手系的图片可以很容易了解到这一点),同样有: 
x=zsinθ+xcosθx′=zsinθ+xcosθ 
y=yy′=y 
z=zcosθxsinθz′=zcosθ−xsinθ 
写成(4x4)矩阵的形式 

⎡⎣⎢⎢⎢xyz1⎤⎦⎥⎥⎥=⎡⎣⎢⎢⎢cosθ0sinθ00100sinθ0cosθ00001⎤⎦⎥⎥⎥⎡⎣⎢⎢⎢xyz1⎤⎦⎥⎥⎥[x′y′z′1]=[cosθ0sinθ00100−sinθ0cosθ00001]∗[xyz1]

 

4.3 绕Z轴旋转

与上面类似,绕Z轴旋转,Z坐标保持不变,xoy组成的平面内正好进行一次二维旋转(和上面讨论二维旋转的情况完全一样) 

⎡⎣⎢⎢⎢xyz1⎤⎦⎥⎥⎥=⎡⎣⎢⎢⎢cosθsinθ00sinθcosθ0000100001⎤⎦⎥⎥⎥⎡⎣⎢⎢⎢xyz1⎤⎦⎥⎥⎥[x′y′z′1]=[cosθ−sinθ00sinθcosθ0000100001]∗[xyz1]

 

4.4 小结

上面描述了三维变换中绕单一轴旋转的矩阵表达形式,绕三个轴旋转的矩阵很类似,其中绕y轴旋转的矩阵与绕x和z轴旋转的矩阵略有点不同(主要是三个轴向顺序和书写矩阵的方式不一致导致的,绕三个不同坐标旋转轴以及其他二个坐标轴组成平面的顺序是: XYZ(绕x轴) YZX(绕y轴) ZXY(绕z轴),其中绕y轴旋转,其他两个轴是ZX,这和我们书写矩阵按

⎡⎣⎢⎢⎢xyz1⎤⎦⎥⎥⎥[xyz1]


的方式不一致,而导致看起来绕Y轴旋转的矩阵似乎是和其他两个矩阵不一致。如果我们颠倒写法,将公式写成 

⎡⎣⎢⎢⎢zyx1⎤⎦⎥⎥⎥=⎡⎣⎢⎢⎢cosθ0sinθ00100sinθ0cosθ00001⎤⎦⎥⎥⎥⎡⎣⎢⎢⎢zyx1⎤⎦⎥⎥⎥[z′y′x′1]=[cosθ0−sinθ00100sinθ0cosθ00001]∗[zyx1]


的方式,那么这三个旋转矩阵看起来在形式上就统一了,都是 

[cosθsinθsinθcosθ][cosθ−sinθsinθcosθ]


这种表现形式了(左上角都是sinθ−sinθ)

 

5. 绕任意轴的三维旋转

绕任意轴的三维旋转可以使用类似于绕任意点的二维旋转一样,将旋转分解为一些列基本的旋转。绕任意轴旋转如下图所示:

RotateArbitrary

P点绕向量u旋转θθ角,得到点Q,已知P点的坐标和向量u,如何求Q点的坐标。 
我们可以把向量u进行一些旋转,让它与z轴重合,之后旋转P到Q就作了一次绕Z轴的三维基本旋转,之后我们再执行反向的旋转,将向量u变回到它原来的方向,也就是说需要进行的操作如下: 
1. 将旋转轴u绕x轴旋转至xoz平面 
2. 将旋转轴u绕y轴旋转至于z轴重合 
3. 绕z轴旋转θθ角 
4. 执行步骤2的逆过程 
5. 执行步骤1的逆过程 
原始的旋转轴u如下图所示:

OriginVector_u 
第1、2、3步骤如下图所示: 
Step2 
Step3 
Step4

步骤1将向量u旋转至xoz平面的操作是一个绕x轴的旋转操作,步骤2将向量u旋转到与z轴重合,第1、2步骤的示意图如下:

RotateToZ 
作点P在yoz平面的投影点q,q的坐标是(0, b, c),原点o与q点的连线oq和z轴的夹角就是u绕x轴旋转的角度。通过这次旋转使得u向量旋转到xoz平面(图中的or向量)【步骤1】 
过r点作z轴的垂线,or与z轴的夹角为ββ, 这个角度就是绕Y轴旋转的角度,通过这次旋转使得u向量旋转到与z轴重合【步骤2】

步骤1中绕x轴旋转的是一次基本的绕x轴的三维旋转,按照之前的讨论,旋转矩阵是: 

⎡⎣⎢⎢⎢10000cosθsinθ00sinθcosθ00001⎤⎦⎥⎥⎥[10000cosθ−sinθ00sinθcosθ00001]


这里的θθ就是图中所示的αα角 (注意αα角度是绕x旋转的正的角度) 
从图中我们还可以得到: 

cosα=c(b2+c2)−−−−−−−√cosα=c(b2+c2)


sinα=b(b2+c2)−−−−−−−√sinα=b(b2+c2)


于是旋转矩阵(记作 Rx(α)Rx(α))为: 

⎡⎣⎢⎢⎢⎢⎢⎢⎢10000c(b2+c2)√b(b2+c2)√00b(b2+c2)√c(b2+c2)√00001⎤⎦⎥⎥⎥⎥⎥⎥⎥[10000c(b2+c2)−b(b2+c2)00b(b2+c2)c(b2+c2)00001]


在完成步骤1之后,向量u被变换到了r的位置,我们继续步骤2的操作,绕y轴旋转负的ββ角(注意:这里的ββ是负的),经过这次变换之后向量u与z轴完全重合,由于这一步也是执行的一次绕Y轴的基本旋转,旋转矩阵(记作 Ry(β)Ry(−β))为: 

⎡⎣⎢⎢⎢cosθ0sinθ00100sinθ0cosθ00001⎤⎦⎥⎥⎥[cosθ0sinθ00100−sinθ0cosθ00001]


使用β−β替换表达式中的θθ,此外根据图中描述,我们可以计算得到: 

cosβ=(b2+c2)−−−−−−−√(a2+b2+c2)−−−−−−−−−−−√cosβ=(b2+c2)(a2+b2+c2)


sinβ=a(a2+b2+c2)−−−−−−−−−−−√sinβ=a(a2+b2+c2)


带入上面的表达式,于是旋转矩阵(记作 Ry(β)Ry(−β))为: 

⎡⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢(b2+c2)√(a2+b2+c2)√0a(a2+b2+c2)√00100a(a2+b2+c2)√0(b2+c2)√(a2+b2+c2)√00001⎤⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥[(b2+c2)(a2+b2+c2)0−a(a2+b2+c2)00100a(a2+b2+c2)0(b2+c2)(a2+b2+c2)00001]

 

在完成前面两个步骤之后,u方向和z轴完全重合,因此执行旋转θθ角,执行的是一次绕z轴的基本三维旋转(记作 R(θ)R(θ),根据之前的讨论,我们可以得到: 

⎡⎣⎢⎢⎢cosθsinθ00sinθcosθ0000100001⎤⎦⎥⎥⎥[cosθ−sinθ00sinθcosθ0000100001]


最后两步骤是前面1和2的逆操作,也就是绕Y轴旋转ββ 和绕X轴旋转α−α,这两个矩阵分别记作 Ry(β)Ry(β) 和 Rx(α)Rx(−α),得到它们的方式很简单,只需要将上面步骤1和步骤2中的角度修改成相反数即可,也就是:

 

 

Ry(β)=⎡⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢(b2+c2)√(a2+b2+c2)√0a(a2+b2+c2)√00100a(a2+b2+c2)√0(b2+c2)√(a2+b2+c2)√00001⎤⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥Ry(β)=[(b2+c2)(a2+b2+c2)0a(a2+b2+c2)00100−a(a2+b2+c2)0(b2+c2)(a2+b2+c2)00001]


Rx(α)=⎡⎣⎢⎢⎢⎢⎢⎢⎢10000c(b2+c2)√b(b2+c2)√00b(b2+c2)√c(b2+c2)√00001⎤⎦⎥⎥⎥⎥⎥⎥⎥Rx(−α)=[10000c(b2+c2)b(b2+c2)00−b(b2+c2)c(b2+c2)00001]

 

最终得到 绕任意轴u旋转的旋转矩阵是【因为使用的列向量,因此执行的是左乘(从右往左)】:

 

MR=Rx(α)Ry(β)Rz(θ)Ry(β)Rx(α)=MR=Rx(−α)Ry(β)Rz(θ)Ry(−β)Rx(α)=


roateMatrix 
(注:式中的(u,v,w)对应上文中向量(a,b,c),公式我自己笔算过,为了减少编辑公式的时间(使用LaTex编辑太繁琐,因此找了一张公式的图片贴在此处)

 

如果向量是经过单位化的(单位向量),那么有a2+b2+c2=1a2+b2+c2=1,可以简化上述的公式,得到:

NormalizedRotate

参考文献:

    1. Wiki Rotation (mathematics)
    2. Euler’s rotation theorem
    3. Maths - Rotation Matrices
    4. 绕任意轴旋转
    5. Rotation About an Arbitrary Axis in 3 Dimensions
    6. Rotation about an Arbitrary Axis (Line)

转载于:https://www.cnblogs.com/h2zZhou/p/9074126.html

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

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

相关文章

数据预处理 泰坦尼克号_了解泰坦尼克号数据集的数据预处理

数据预处理 泰坦尼克号什么是数据预处理? (What is Data Pre-Processing?) We know from my last blog that data preprocessing is a data mining technique that involves transforming raw data into an understandable format. Real-world data is often incom…

Pytorch中DNN入门思想及实现

DNN全连接层(线性层) 计算公式: y w * x b W和b是参与训练的参数 W的维度决定了隐含层输出的维度,一般称为隐单元个数(hidden size) b是偏差值(本文没考虑) 举例: 输…

IDEA去除mapper.xml文件中的sql语句的背景色

2019独角兽企业重金招聘Python工程师标准>>> IDEA版本 2017.3 mapper.xml文件中的sql语句,总是黄色一大片,看起来不舒服。 按如下设置进行设置即可 此时设置完还有点背景色 再进行一个设置 Ok,完美解决 转载于:https://my.oschina.net/u/3939…

vc6.0 绘制散点图_vc有关散点图的一切

vc6.0 绘制散点图Scatterplots are one of the most popular visualization techniques in the world. Its purposes are recognizing clusters and correlations in ‘pairs’ of variables. There are many variations of scatter plots. We will look at some of them.散点图…

Pytorch中RNN入门思想及实现

RNN循环神经网络 整体思想: 将整个序列划分成多个时间步,将每一个时间步的信息依次输入模型,同时将模型输出的结果传给下一个时间步,也就是说后面的结果受前面输入的影响。 RNN的实现公式: 个人思路: 首…

小扎不哭!FB又陷数据泄露风波,9000万用户受影响

对小扎来说,又是多灾多难的一个月。 继不久前Twitter曝出修补了一个可能造成数以百万计用户私密消息被共享给第三方开发人员的漏洞,连累Facebook股价跟着短线跳水之后,9月28日,Facebook又双叒叕曝出因安全漏洞遭到黑客攻击&#…

在衡量欧洲的政治意识形态时,调查规模的微小变化可能会很重要

(Related post: On a scale from 1 to 10, how much do the numbers used in survey scales really matter?)(相关文章: 从1到10的量表,调查量表中使用的数字到底有多重要? ) At Pew Research Center, survey questions about respondents’…

Pytorch中CNN入门思想及实现

CNN卷积神经网络 基础概念: 以卷积操作为基础的网络结构,每个卷积核可以看成一个特征提取器。 思想: 每次观察数据的一部分,如图,在整个矩阵中只观察黄色部分33的矩阵,将这【33】矩阵(点乘)权重得到特…

事件映射 消息映射_映射幻影收费站

事件映射 消息映射When I was a child, I had a voracious appetite for books. I was constantly visiting the library and picking new volumes to read, but one I always came back to was The Phantom Tollbooth, written by Norton Juster and illustrated by Jules Fei…

前端代码调试常用

转载于:https://www.cnblogs.com/tabCtrlShift/p/9076752.html

Pytorch中BN层入门思想及实现

批归一化层-BN层(Batch Normalization) 作用及影响: 直接作用:对输入BN层的张量进行数值归一化,使其成为均值为零,方差为一的张量。 带来影响: 1.使得网络更加稳定,结果不容易受到…

匿名内部类和匿名类_匿名schanonymous

匿名内部类和匿名类Everybody loves a fad. You can pinpoint someone’s generation better than carbon dating by asking them what their favorite toys and gadgets were as a kid. Tamagotchi and pogs? You were born around 1988, weren’t you? Coleco Electronic Q…

Pytorch框架中SGD&Adam优化器以及BP反向传播入门思想及实现

因为这章内容比较多,分开来叙述,前面先讲理论后面是讲代码。最重要的是代码部分,结合代码去理解思想。 SGD优化器 思想: 根据梯度,控制调整权重的幅度 公式: 权重(新) 权重(旧) - 学习率 梯度 Adam…

朱晔和你聊Spring系列S1E3:Spring咖啡罐里的豆子

标题中的咖啡罐指的是Spring容器,容器里装的当然就是被称作Bean的豆子。本文我们会以一个最基本的例子来熟悉Spring的容器管理和扩展点。阅读PDF版本 为什么要让容器来管理对象? 首先我们来聊聊这个问题,为什么我们要用Spring来管理对象&…

ab实验置信度_为什么您的Ab测试需要置信区间

ab实验置信度by Alos Bissuel, Vincent Grosbois and Benjamin HeymannAlosBissuel,Vincent Grosbois和Benjamin Heymann撰写 The recent media debate on COVID-19 drugs is a unique occasion to discuss why decision making in an uncertain environment is a …

基于Pytorch的NLP入门任务思想及代码实现:判断文本中是否出现指定字

今天学了第一个基于Pytorch框架的NLP任务: 判断文本中是否出现指定字 思路:(注意:这是基于字的算法) 任务:判断文本中是否出现“xyz”,出现其中之一即可 训练部分: 一&#xff…

支撑阻力指标_使用k表示聚类以创建支撑和阻力

支撑阻力指标Note from Towards Data Science’s editors: While we allow independent authors to publish articles in accordance with our rules and guidelines, we do not endorse each author’s contribution. You should not rely on an author’s works without seek…

高版本(3.9版本)python在anaconda安装opencv库及skimage库(scikit_image库)诸多问题解决办法

今天开始CV方向的学习,然而刚拿到基础代码的时候发现 from skimage.color import rgb2gray 和 import cv2标红(这里是因为我已经配置成功了,所以没有红标),我以为是单纯两个库没有下载,去pycharm中下载ski…

单机安装ZooKeeper

2019独角兽企业重金招聘Python工程师标准>>> zookeeper下载、安装以及配置环境变量 本节介绍单机的zookeeper安装,官方下载地址如下: https://archive.apache.org/dist/zookeeper/ 我这里使用的是3.4.11版本,所以找到相应的版本点…

均线交易策略的回测 r_使用r创建交易策略并进行回测

均线交易策略的回测 rR Programming language is an open-source software developed by statisticians and it is widely used among Data Miners for developing Data Analysis. R can be best programmed and developed in RStudio which is an IDE (Integrated Development…