当我传入一个向量(V),我希望你能帮我创建一个旋转矩阵(M),其中M * [0,0,1] (向前) = V
。
我之所以要这样做,是因为我希望使用这个矩阵来乘以其他向量,以将它们放置在本地空间中(不确定这是否是正确的术语,但希望您能理解)。
V = [0, 1, 0]
M = ?
Result = M * V = [0, 0, -1]
如果[0,0,1]
通过乘以矩阵M
后向上旋转90度变成了[0,1,0]
,那么这个M
是什么呢?
当我传入一个向量(V),我希望你能帮我创建一个旋转矩阵(M),其中M * [0,0,1] (向前) = V
。
我之所以要这样做,是因为我希望使用这个矩阵来乘以其他向量,以将它们放置在本地空间中(不确定这是否是正确的术语,但希望您能理解)。
V = [0, 1, 0]
M = ?
Result = M * V = [0, 0, -1]
如果[0,0,1]
通过乘以矩阵M
后向上旋转90度变成了[0,1,0]
,那么这个M
是什么呢?
/1 0 0 \
|0 cos θ -sin θ|
\0 sin θ cos θ/
/1 0 0\
|0 0 1|
\0 -1 0/
记住角度可以用度或弧度表示,因此如果您在代码中实现更通用的旋转,需要检查您的数学库期望什么。
我也曾经遇到过同样的问题。但是如果有人需要,我在这里找到了一种适当的方法来解决这个问题 [https://math.stackexchange.com/questions/180418/calculate-rotation-matrix-to-align-vector-a-to-vector-b-in-3d/]
以下是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;
注意:如果a=-b,则会失败
给定本地 z-轴 V=(vx,vy,vz)
和本地 x-轴指向 U=(ux,uy,uz)
,其中U
和V
是单位向量:
本地 y-轴为 W=Normalized(Cross(V,U))
。现在如果 U
不完全垂直于 V
,则需要使用 U=Normalized(Cross(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)
创建一个单位向量。 [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 ]