如何在THREE.js中找到两个向量之间的旋转矩阵

18

我正在寻找在THREE.js中查找两个定义向量之间旋转矩阵的方法。

例如

v1 = new THREE.Vector3(1, 1, 1) v2 = new THREE.Vector3(1, 1, -1)

我需要这个旋转矩阵来在下一步旋转整个对象。


1
这是一个非 Stack Overflow 的问题,顺便看一下这里:http://gamedev.stackexchange.com/questions/20097/how-to-calculate-a-3x3-rotation-matrix-from-2-direction-vectors - Luca Davanzo
这是Vector3文档的链接:http://threejs.org/docs/#Reference/Math/Vector3 - Luca Davanzo
这个问题似乎不适合讨论,因为它涉及到http://math.stackexchange.com/。 - Luca Davanzo
2个回答

31
您可以通过两个单位长度向量v1v2来定义旋转,如下所示:
var quaternion = new THREE.Quaternion(); // create one and reuse it

quaternion.setFromUnitVectors( v1, v2 );

在您的情况下,您需要先对向量进行归一化处理。

然后,您可以使用以下模式将该旋转应用于对象:

var matrix = new THREE.Matrix4(); // create one and reuse it

matrix.makeRotationFromQuaternion( quaternion );

object.applyMatrix4( matrix );

另外,如果您不需要矩阵,可以直接应用四元数:

object.applyQuaternion( quaternion );

three.js r.152


嗨。谢谢,这似乎起作用了。不过最好能有一个不依赖于四元数的解决方案。 - kriskodzi
4
three.js 基于四元数。但如果您坚持使用它,首先对矢量进行归一化,然后设置 axis.cross( v1, v2 ); angle = v1.angleTo( v2 ); matrix.makeRotationAxis( axis, angle ); object.applyMatrix( matrix ); - WestLangley
是的,这正是我正在寻找的。我认为您可以将此添加到您的答案中,然后我会将其标记为已接受。 - kriskodzi
4
我在回答中提供的方法是最具数值稳定性的,并且是我建议用户使用的方法。(顺带一提,第二种方法与轴角依赖性有关--在任一情况下都需要一个中间步骤。如果两个向量平行,则轴角未被明确定义。) - WestLangley

1
我不使用四元数,而是这样做(也不使用THREE.js):
为第一个向量V1构建4x4变换矩阵(V1、V2位于其XY平面上,且V1是X轴)。
double V1[3],V2[3]; // input
double X[3],Y[3],Z[3],P[3]; // output
double m[16]; // OpenGL like transform matrix
X = V1;
Z = V1 x V2;
Y = X x Z;
X/=|X|;
Y/=|Y|;
Z/=|Z|;
P = (0,0,0);
m[ 0]=X[0];
m[ 1]=X[1];
m[ 2]=X[2];
m[ 3]=0;
m[ 4]=Y[0];
m[ 5]=Y[1];
m[ 6]=Y[2];
m[ 7]=0;
m[ 8]=Z[0];
m[ 9]=Z[1];
m[10]=Z[2];
m[11]=0;
m[12]=P[0];
m[13]=P[1];
m[14]=P[2];
m[15]=1;

现在在它上面应用绕Z轴的旋转变换矩阵。
double angle = acos( (V1.v2)/(|V1|.|V2|) )
  • 绕 Z 轴旋转 +/- 角度
  • 角度符号取决于 Y 轴叉积操作数的顺序
  • 现在不确定,但你会看到的
  • 如果设置错误,则 V2 将位于相反侧面

嗨,谢谢你的提示,我只是在测试它。你说的“在其上应用绕Z轴的旋转变换矩阵”是什么意思?你是想让我将矩阵应用于对象,然后围绕Z轴旋转,这样我们就需要应用两次旋转了吗? - kriskodzi
1
@RecRoot m[] 包含表示 V1 坐标系的变换矩阵。您需要将矩阵 m 乘以绕 Z 轴旋转角度的旋转矩阵,该旋转矩阵将坐标系从 V1 旋转到 V2。无论您是应用 objectmrotz 还是 M=mrotz 然后 objM,都没有关系,唯一的区别在于当您创建 M 时,您可以减少操作次数(仅一次将矩阵乘以矩阵,而不是为每个对象顶点都进行一次操作...)。您可以通过谷歌搜索如何查看绕 Z 轴旋转的变换矩阵(这是基本的,我认为您的框架在某些函数中本地支持)。 - Spektre
@RecRoot 顺便看一下这里:https://dev59.com/QYLba4cB1Zd3GeqPck_c#25216549,了解更多有关变换矩阵组合的信息。 - Spektre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接