为什么在 Z 轴上平移矩阵与将 Z 轴上的位置改变相同的数字不同?

Why translating matrix on Z axis is not the same as changing position on the Z axis by same number?

我有一个原点在底部的网格。我想在 Z 轴上将它移动 -132。如果我改变网格的位置,它就在正确的位置。但是如果我将它在 Z 轴上平移 -132,网格将关闭 20。为什么我没有得到相同的结果?

我翻译矩阵的方式:

matrix = new THREE.Matrix4().makeTranslation( 0, 0, -132 )
mesh.geometry.applyMatrix( matrix );

这是网格的图像:

这里是 132 翻译后的图像。它是 20。

更多信息: 网格的位置在: 419, -830, 500

并且旋转是: 0, -0.52, 0

所以Z坐标在500;但我必须将它向下移动 -132。如果它通过将位置向下移动 132 来移动它,则它处于正确的位置。但我想平移矩阵以使原点下降 132。 这也是矩阵:

"matrix": [0.8660253882408142,0,0.5,0,0,1,0,0,-0.5,0,0.8660253882408142,0,419,-830,500,1]

进一步澄清和聊天后更新

整个观点是 3D 变换 不是 可交换的。这意味着平移然后旋转与旋转然后平移不同(会产生不同的结果)。在某些特殊情况下,这些可能会重合(例如,起源位于 0,0,0 等等......),但通常它们会有不同的结果。

此外,相对坐标和将 3D 对象嵌套在其他 3D 对象中也存在问题。对象的最终(世界)变换会受到影响,无论它是否在其他对象内部。

最后,实际 mesh position (local transform) 相对于顶点的位置在网格(和几何体)将(最终)投影到 2D 的方式中发挥作用,因此投影角度会发生变化(见上文)。

如前所述,问题是关于以移动原点的方式移动网格,因此可以针对这个移动的原点进行进一步的转换(例如旋转)。在 3D 编程中,实现此行为的标准方法是在网格周围包含枢轴或包装器,并将网格相对于包装器定位在相对内部。然后在包装器本身上应用任何进一步的转换(例如旋转)。这给出了网格相对于另一个轴(而不是中心)旋转的效果。

发生这种情况的方式是包装器确实围绕其自身的原点旋转(即在 0,0,0 处),但内部的网格发生了移动,因此它看起来像是相对于另一个轴旋转。一个常见的例子是为 3D 车轮建模,它可以绕其自身的轴旋转(即旋转),但也可以与汽车的其余部分一起平移。因此,在车轮周围添加了一个包装纸,包装纸确实与汽车的其余部分平移,但车轮在包装纸内旋转,就好像没有平移一样(与您在这里需要的情况相反,但有相同的区别).

您可能需要检查 MOD3 pivot modifier,它创建自定义枢轴作为原点 points/axes(ps 我是端口的作者)。 MOD3中还包含一个轮子修改器,解决了上面描述的3D轮子问题。

要在您的代码中使用包装器 3D 对象,请执行以下操作:

// create the pivot wrapper
var pivot = new THREE.Object3D();
pivot.name = "PIVOT";
pivot.add( mesh );
scene.add( pivot );

// shift the mesh inside pivot
mesh.position.set(0,0,-132);
// position wrapper in the scene, 
// position in the place where mesh would be
pivot.position.set(419, -830, 500);
pivot.rotation.set(0, -0.52, 0);
// now mesh appears rotated around the z = -132 axis instead of the center
// because the wrapper is actually rotated around its center,
// but its center coincides with the shifted mesh by z = -132

相关回答here