Math 基于两个向量创建旋转矩阵
我希望在传入向量(V)时创建一个旋转矩阵(M),其中Math 基于两个向量创建旋转矩阵,math,vector,matrix,rotation,Math,Vector,Matrix,Rotation,我希望在传入向量(V)时创建一个旋转矩阵(M),其中M*[0,0,1](向前)=V 我这样做是因为我想用这个矩阵乘以其他向量,把它们放到局部空间(不确定这是否是正确的术语,但希望你能理解) 因此,如果[0,0,1]在乘以M之后向上倾斜90度,变成[0,1,0]。。。什么是M?即使是用手,也很简单,很简单。仅通过检查,可以看出M基本上交换了y轴和z轴,而x轴则单独存在 此阵列执行以下任务: [1 0 0] M = [0 0 1] [0 -1 0] M * [0, 1,
M*[0,0,1](向前)=V
我这样做是因为我想用这个矩阵乘以其他向量,把它们放到局部空间(不确定这是否是正确的术语,但希望你能理解)
因此,如果
[0,0,1]
在乘以M之后向上倾斜90度,变成[0,1,0]
。。。什么是M
?即使是用手,也很简单,很简单。仅通过检查,可以看出M基本上交换了y轴和z轴,而x轴则单独存在
此阵列执行以下任务:
[1 0 0]
M = [0 0 1]
[0 -1 0]
M * [0, 1, 0] = [0, 0, -1]
请注意,在对这两个特定向量具有相同影响的变换矩阵集合中,此解决方案不是唯一的。事实上,有无限多这样的矩阵。这里有一个:
[sqrt(2)/2 0 sqrt(2)/2]
M2 = [sqrt(2/2) 0 -sqrt(2)/2]
[0 -1 0 ]
三维旋转很难思考,甚至在文本中更难解释。然而,你可以把左手变成一组近似的三维轴。看看下面描述弗莱明左手法则的维基百科页面;特别是,请看第二张图,图中的手指标记为I、B和F: 用你自己的手做同样的形状,而不是标记手指I、B和F,让我们称它们为x、y和z。此外,我们会说,这三个手指在手掌处相交的点是原点,即点(0),从原点向其中一个手指/拇指的尖端移动是正向移动的 向量v=(0110)是食指上的一个点(我们称之为y)。我们希望旋转此点以形成点(0-1)。该点位于z轴(拇指)上,但它是负数,因此它位于原点“下方”一个单位处,从拇指尖到原点的方向 所以,要将点(0 1 0)旋转为(0 0-1),我们需要绕x轴(你的中指)旋转它。想象一下,将一张光盘放在中指上,推动它,使其位于食指和拇指定义的平面上(x,y)平面上,并在光盘上从其中心一个单位处做标记。现在想象一下,将该标记与食指对齐,使该标记位于点(0 1 0)处。您可以围绕中指旋转光盘,使标记位于点(0-1)处。因此,所需的旋转是围绕x轴的旋转 下面的Wikipedia页面为您提供了以下公式。绕x轴旋转的矩阵为: 如果要用右手旋转圆盘,则定义矩阵,以便θ的负值对应右手的顺时针运动(反之亦然,正值)。我们需要旋转的角度为负四分之一圈,因此所需矩阵为:
/1 0 0\
|0 0 1|
\0 -1 0/
请记住,角度可以用度或弧度表示,因此,如果在代码中实现更一般的旋转,则需要检查数学库的期望值。因此,您将获得一个局部z-轴
V=(vx,vy,vz)
和一个朝向U=(ux,uy,uz)的局部x-轴,其中U
和V
是单位向量:
局部y轴是W=标准化(交叉(V,U))
。现在,如果U
与V
不完全垂直,则需要使用U=归一化(交叉(W,V))
3×3旋转矩阵为
| Ux Wx Vx |
M = | Uy Wy Vy |
| Uz Wz Vz |
请注意,Cross(A,B)=(Ay*Bz-Az*By,Az*Bx-Ax*Bz,Ax*By-Ay*Bz)
是叉积运算符,Normalized(A)=(Ax,Ay,Az)/SQRT(Ax*Ax+Ay*Ay+Az*Az)
创建了一个单位向量。我还必须解决同样的问题。尽管如此,还是有人需要这个我在这里找到了一个合适的方法
下面是如何用c计算的++
Eigen::Vector3f a(34, 0, 1);
Eigen::Vector3f b(2, 2, 1);
a = a/a.norm();
float b_norm = b.norm();
b = b/b_norm;
Eigen::Vector3f v = a.cross(b);
float s = v.norm();
float c = a.dot(b);
Eigen::Matrix3f vx;
vx << 0, -v[2], v[1], v[2], 0, -v[0], -v[1], v[0], 0;
Eigen::Matrix3f r = Eigen::Matrix3f::Identity(3,3);
if(s != 0 ){
r = r + vx + vx*vx*((1-c)/std::pow(s, 2));
}else{
std::cout<< "doesn't work if a == -b"<< std::endl;
}
std::cout<<"Testing..."<< std::endl;
std::cout << "b: " << b.transpose() << std::endl;
std::cout << "After projected: b: "<< (r*a).transpose() << std::endl;
Eigen::vector3fa(34,0,1);
本征::向量3B(2,2,1);
a=a/a.标准();
浮动b_范数=b.范数();
b=b/b_标准;
本征::向量3f v=a.交叉(b);
浮点数s=v.norm();
浮点数c=a.dot(b);
本征::矩阵x3f vx;
vx可能值得指出的是,虽然有无穷多个变换矩阵映射(0 1 0)到(0 0-1),但并非所有变换矩阵都是旋转矩阵。此外,在旋转矩阵中,执行的旋转必须是围绕y轴和z轴的自然整圈数,以及围绕x轴的自然整圈数加上四分之一圈(在适当方向)的总和绕x轴旋转。相关问题:旋转矩阵的列对应于局部x、y、z轴的组件。
| Ux Wx Vx |
M = | Uy Wy Vy |
| Uz Wz Vz |
Eigen::Vector3f a(34, 0, 1);
Eigen::Vector3f b(2, 2, 1);
a = a/a.norm();
float b_norm = b.norm();
b = b/b_norm;
Eigen::Vector3f v = a.cross(b);
float s = v.norm();
float c = a.dot(b);
Eigen::Matrix3f vx;
vx << 0, -v[2], v[1], v[2], 0, -v[0], -v[1], v[0], 0;
Eigen::Matrix3f r = Eigen::Matrix3f::Identity(3,3);
if(s != 0 ){
r = r + vx + vx*vx*((1-c)/std::pow(s, 2));
}else{
std::cout<< "doesn't work if a == -b"<< std::endl;
}
std::cout<<"Testing..."<< std::endl;
std::cout << "b: " << b.transpose() << std::endl;
std::cout << "After projected: b: "<< (r*a).transpose() << std::endl;