如果你想要理解
vrrotvec2mat
函数,你需要在深入了解该函数之前先了解旋转的轴角表示。具体来说,你需要理解
罗德里格斯旋转公式,也称为
轴角旋转公式。我会首先对此进行一些介绍来解释这个公式。
在线性代数中,无论是二维还是三维,最常见的旋转点的方式是使用
旋转矩阵。其中你将二维或三维坐标用该旋转矩阵进行预乘(即
y = A*x
,其中
x
表示列向量中的点),从而使该点围绕坐标系原点旋转。你也可以将其视为围绕头部位于二维或三维空间的点的
向量v
进行旋转。
然而,另一种方法是提供所谓的
轴角表示法,这仅在3D空间中有效。轴由描述绕其旋转的矢量
v
的轴心上的单位向量
k
描述,并沿着该轴旋转一个角度,根据
右手规则确定方向。
以下是我从维基百科获得的图例:
![](https://upload.wikimedia.org/wikipedia/commons/thumb/a/a7/Rodrigues-formula.svg/600px-Rodrigues-formula.svg.png)
来源: Rodrigues' Rotation formula
在我们的例子中,向量k
指向正上方,向量v
指向45度西北方向。我们希望围绕由向量k
定义的轴旋转180度,如果您这样做,vrot
就是旋转后的向量。v||
和v_|_
是相对于向量k
的v
的平行和垂直投影。这些被用来推导Rodrigues公式,但我不会在这里详细说明。如果您想要完整的推导,请参阅文章。
提出Rodrigues旋转公式的原因是,经常有应用需要围绕非位于原点的轴旋转,也不是相对于标准的x
、y
和z
轴旋转。
事实上,如果您查看维基百科文章,您不需要将其转换为矩阵形式来旋转物体。您可以直接使用单位向量和旋转角度来旋转向量,这导致了他的旋转公式:
![](https://upload.wikimedia.org/math/9/0/1/901dd9781f42688508da7bb6bbac9e7d.png)
来源: Rodrigues旋转公式
vrrotvec2mat
之所以存在,是因为您可以在线性代数中将旋转向量的轴角表示和相对于原点的旋转矩阵进行转换。然后,您可以应用同样的线性代数理论来旋转3D空间中的向量/点,给定这个旋转矩阵。通过使用vrrotvec2mat
和vrrotmat2vec
,您可以在常规旋转矩阵和Rodrigues公式表示之间进行转换。
轴角表示法本质上是一个四元素向量,其中前三个元素是定义旋转轴的单位向量 k 的 x、y 和 z 分量,最后一个元素是绕该轴旋转的旋转角度 theta。在这里,vrrotvec2mat 也不例外,需要按照我刚才讲的顺序使用四元素向量。但是,从源代码中快速查看,theta 是以弧度为单位定义的。
如果您想要一个具体的例子来展示这个过程,让我们以上图为例。单位向量
k
指向
z
轴向上,因此前三个分量为
(0,0,1)
。我们希望旋转180度,因此第四个参数是
pi
... 所以:
>> M = vrrotvec2mat([0 0 1 pi])
M =
-1.0000 -0.0000 0
0.0000 -1.0000 0
0 0 1.0000
如果您查看笛卡尔坐标系中围绕z
轴的标准旋转矩阵,这确切地定义了一个180度的旋转。如果您回想一下此旋转的旋转矩阵,它是:
![enter image description here](https://istack.dev59.com/yxvSX.webp)
如果你在上面的矩阵中替换
theta = pi
,你将得到与
vrrot2vec2mat
函数中看到的相同的东西作为
M
。然而,忽略第一行第二列的符号,因为它是由于数值精度引起的...这就带我们来到第二个参数
options
。基本上,当使用Rodrigues旋转公式计算旋转矩阵值时,矩阵中的值有时会非常小。
options
结构体有一个名为
epsilon
的字段,您可以指定在矩阵计算完成后,任何小于此阈值的值都被认为是零。我认为默认的
1e-12
非常合适。
如果您想更改默认的
epsilon
,只需创建一个具有单个元素
epsilon
的结构,并使用此附加的第二个参数调用函数...所以类似这样的东西:
>> options.epsilon = 1e-15
>> M = vrrotvec2mat([0 0 1 pi], options)
无论如何,回到我们之前谈论的话题,假设我们给定的向量
v
是相对于上图所示的,并且它指向西北方向 - 具体来说是在
(x,y,z) = (1,0,1)
处。如果我们使用这个旋转矩阵来旋转这个点,我们应该能够使它与
xz
平面平行并指向相反的方向,因此我们应该得到
(x,y,z) = (-1,0,1)
。
>> M*[1;0;1]
ans =
-1.0000
0.0000
1.0000
你也可以使用Rodrigues旋转公式获得相同的结果:
>> v = [1;0;1];
>> k = [0;0;1];
>> theta = pi;
>> vrot = v*cos(theta) + cross(k,v)*sin(theta) + k*(k.'*v)*(1-cos(theta))
vrot =
-1.0000
0.0000
1.0000
总的来说,这只是围绕任意轴旋转向量的另一种方式,不仅局限于标准的
x
、
y
或
z
。
vrrotvec
应该会给你所需的r
。 - Adriaan