I have a line (actually a cube) going from (x1,y1,z1) to (x2,y2,z2). I would like to rotate it so that it is aligned along another line going from (x3,y3,z3) to (x4,y4,z4). Presently I am using Math::Atan2
along with Matrix::RotateYawPitchRoll
. Any better ways to do this?
我有一条线(实际上是一个立方体)从(x1,y1,z1)到(x2,y2,z2)。我想旋转它,使其沿着从(x3,y3,z3)到(x4,y4,z4)的另一条线对齐。目前我正在使用Math :: Atan2以及Matrix :: RotateYawPitchRoll。有更好的方法吗?
Edit: I think I've worded this post very badly. What I am actually looking for is a Rotation Matrix from two Vectors.
编辑:我想我的帖子非常糟糕。我实际上寻找的是两个向量的旋转矩阵。
2 个解决方案
#1
4
Yes you can do this without needing to think in terms of angles at all.
是的,你可以做到这一点,而不需要考虑角度。
Since you have a cube, suppose you pick one corner and then define the 3 edges radiating out from it as vectors f0, f1, f2 (these are direction vectors, relative to the corner you've picked). Normalise those and write them as columns in a matrix F
由于你有一个立方体,假设你选择一个角,然后定义从它向外辐射的3个边作为向量f0,f1,f2(这些是方向向量,相对于你选择的角)。将它们标准化并将它们写为矩阵F中的列
(f0x f1x f2x)
(f0y f1y f2y)
(f0z f1z f2z)
Now do the same thing for the vectors t0, t1, t2 of the cube you want to rotate to and call it matrix T.
现在对要旋转的立方体的向量t0,t1,t2执行相同的操作并将其称为矩阵T.
Now the matrix R = T * Inverse(F) is the matrix which rotates from the orientation of the first cube to the orientation of the second (because inverse F maps e.g f0 to (1 0 0)', and then T maps (1 0 0)' to t0).
现在矩阵R = T * Inverse(F)是从第一个立方体的方向旋转到第二个立方体的方向的矩阵(因为反F映射例如f0到(1 0 0)',然后是T映射(1) 0 0)'到t0)。
If you want to know why this works, think in terms of coordinate system basis vectors: if you want to rotate the X Y and Z axes to a new coordinate system, well the columns of the rotation matrix are just the vectors you want (1 0 0)', (0 1 0)' & (0 0 1)' to be mapped to. T*Inverse(F) is effectively rotating your cube from its original orientation to axis aligned, and then to the desired orientation.
如果你想知道它的工作原理,请考虑坐标系基础向量:如果你想将XY和Z轴旋转到一个新的坐标系,那么旋转矩阵的列就是你想要的向量(1 0) 0)',(0 1 0)'和(0 0 1)'映射到。 T *反向(F)有效地将立方体从其原始方向旋转到轴对齐,然后到期望的方向。
(Sorry, above is for column vectors and transforms on the left, OpenGL style. I seem to remember Direct3D is row vectors and transforms on the right, but it should be obvious how to switch it around).
(对不起,上面是左边的列向量和变换,OpenGL样式。我似乎记得Direct3D是行向量并且在右边转换,但是应该很明显如何切换它)。
It also applies equally well to 4x4 matrices with a translation component too.
它也同样适用于带有转换组件的4x4矩阵。
#2
0
You might want to add how to actually interpolate the matrices. Source and destination matrices are fine in your answer, but computing the inverse is pointless. Quaternions will give you the shortest rotational path, so take the rotational 3x3 matrices on both matrices, convert to quaternions and lerp those. Do a separate lerp for the translation and recompose. Google for quaternion - matrix and back conversions and quaternion lerp.
您可能想要添加如何实际插值矩阵。源答案和目标矩阵在你的答案中很好,但计算逆矩阵毫无意义。四元数将为您提供最短的旋转路径,因此在两个矩阵上采用旋转3x3矩阵,转换为四元数并对其进行调整。为翻译做一个单独的lerp并重新组合。谷歌的四元数 - 矩阵和反向转换和四元数lerp。
Edit: A rotation matrix from a forward and an up vector is trivial. The missing column is the cross product of the other two vectors. (don't forget to normalize columns).
编辑:来自向前和向上矢量的旋转矩阵是微不足道的。缺失的列是其他两个向量的叉积。 (别忘了规范化列)。
#1
4
Yes you can do this without needing to think in terms of angles at all.
是的,你可以做到这一点,而不需要考虑角度。
Since you have a cube, suppose you pick one corner and then define the 3 edges radiating out from it as vectors f0, f1, f2 (these are direction vectors, relative to the corner you've picked). Normalise those and write them as columns in a matrix F
由于你有一个立方体,假设你选择一个角,然后定义从它向外辐射的3个边作为向量f0,f1,f2(这些是方向向量,相对于你选择的角)。将它们标准化并将它们写为矩阵F中的列
(f0x f1x f2x)
(f0y f1y f2y)
(f0z f1z f2z)
Now do the same thing for the vectors t0, t1, t2 of the cube you want to rotate to and call it matrix T.
现在对要旋转的立方体的向量t0,t1,t2执行相同的操作并将其称为矩阵T.
Now the matrix R = T * Inverse(F) is the matrix which rotates from the orientation of the first cube to the orientation of the second (because inverse F maps e.g f0 to (1 0 0)', and then T maps (1 0 0)' to t0).
现在矩阵R = T * Inverse(F)是从第一个立方体的方向旋转到第二个立方体的方向的矩阵(因为反F映射例如f0到(1 0 0)',然后是T映射(1) 0 0)'到t0)。
If you want to know why this works, think in terms of coordinate system basis vectors: if you want to rotate the X Y and Z axes to a new coordinate system, well the columns of the rotation matrix are just the vectors you want (1 0 0)', (0 1 0)' & (0 0 1)' to be mapped to. T*Inverse(F) is effectively rotating your cube from its original orientation to axis aligned, and then to the desired orientation.
如果你想知道它的工作原理,请考虑坐标系基础向量:如果你想将XY和Z轴旋转到一个新的坐标系,那么旋转矩阵的列就是你想要的向量(1 0) 0)',(0 1 0)'和(0 0 1)'映射到。 T *反向(F)有效地将立方体从其原始方向旋转到轴对齐,然后到期望的方向。
(Sorry, above is for column vectors and transforms on the left, OpenGL style. I seem to remember Direct3D is row vectors and transforms on the right, but it should be obvious how to switch it around).
(对不起,上面是左边的列向量和变换,OpenGL样式。我似乎记得Direct3D是行向量并且在右边转换,但是应该很明显如何切换它)。
It also applies equally well to 4x4 matrices with a translation component too.
它也同样适用于带有转换组件的4x4矩阵。
#2
0
You might want to add how to actually interpolate the matrices. Source and destination matrices are fine in your answer, but computing the inverse is pointless. Quaternions will give you the shortest rotational path, so take the rotational 3x3 matrices on both matrices, convert to quaternions and lerp those. Do a separate lerp for the translation and recompose. Google for quaternion - matrix and back conversions and quaternion lerp.
您可能想要添加如何实际插值矩阵。源答案和目标矩阵在你的答案中很好,但计算逆矩阵毫无意义。四元数将为您提供最短的旋转路径,因此在两个矩阵上采用旋转3x3矩阵,转换为四元数并对其进行调整。为翻译做一个单独的lerp并重新组合。谷歌的四元数 - 矩阵和反向转换和四元数lerp。
Edit: A rotation matrix from a forward and an up vector is trivial. The missing column is the cross product of the other two vectors. (don't forget to normalize columns).
编辑:来自向前和向上矢量的旋转矩阵是微不足道的。缺失的列是其他两个向量的叉积。 (别忘了规范化列)。