为什么在Z轴上平移矩阵不等同于将位置沿Z轴移动相同的距离?

3
我是一名有用的助手,可以为您翻译文本。

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

我翻译矩阵的方式:

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

这是网格的图像: enter image description here 这是经过132次翻译后的图像,偏移了20。 enter image description here 更多信息: 网格的位置在: 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]

你想将 z 坐标设置为 -132 还是将该值添加到网格的现有 z 坐标中?使用 mesh.position.z = -132 可以实现第一种情况,而使用转换矩阵可以实现第二种情况。 - Nikos M.
@NikosM。我想将网格的几何形状移动-132-所以我正在进行平移,但是我没有得到正确的结果。 - Zaay
你应该发布相关的代码,展示所有这些操作,同时尝试在应用翻译矩阵后使用console.log输出网格“z”坐标。 - Nikos M.
@NikosM。感谢您的帮助,但我没有别的要发布的内容了。所有发生的代码都是matrix = new THREE.Matrix4().makeTranslation(0, 0, -132) mesh.geometry.applyMatrix(matrix);当然,由于我们正在翻译几何图形而不是位置,因此平移矩阵后的Z坐标不会改变。 - Zaay
MOD3库中,枢轴修饰器(在这里实现你想要的功能)应用了平移矩阵然后通过负数位移网格位置来进行补偿。 - Nikos M.
显示剩余4条评论
1个回答

1

在进一步澄清和聊天后更新

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

此外,还存在相对坐标的问题以及将 3D 对象嵌套在其他 3D 对象中的问题。一个对象的最终(世界)变换会受到其是否在其他对象内部的影响。

最后,实际的 网格位置(局部变换) 与顶点位置在网格(和几何图形)最终投影到二维时发挥了作用,因此投影角度会改变(见上文)。

如已澄清,问题是关于如何移动网格以便移动原点,这样进一步的变换(例如旋转)可以相对于这个移动后的原点进行。在3D编程中实现此行为的标准方法是在网格周围包含枢轴或包装器,并将网格相对于包装器内部定位。然后在包装器本身上应用任何进一步的变换(例如旋转)。这会使网格绕另一个轴旋转(而不是中心)。
这种情况发生的方式是,包装器确实围绕其自身原点(即在0,0,0处)旋转,但内部的网格被移动,因此它看起来是相对于另一个轴旋转的。这的一个常见例子是建模3D汽车轮毂,它可以绕其自身轴线旋转(即旋转),但也可以与整个汽车一起平移。因此,人们在轮毂周围添加一个包装器,其中包装器确实随着整个汽车一起平移,但轮毂在包装器内部旋转,就好像没有平移存在(这是您需要的反向情况,但本质相同)。
你可能想要检查一下MOD3 pivot modifier,它可以创建自定义的中心点/轴(顺便说一下,我是这个端口的作者)。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

一条相关的答案 在这里

我已经尝试过这个,但是它将矩阵原点移动到完全不同的位置,与预期的不同。我想做的就是在Z轴上将矩阵平移132,并获得与将网格位置移动132相同的结果。您的代码将原点在所有轴上移动到其他位置。 - Zaay
好的,更新答案。显然,由于网格位置不为零,xy轴上的网格位置也会被翻译。请给我一分钟。 - Nikos M.
好的,已更新,请随时检查并回复。如果您发布了代码和用例,会更有帮助,因为各种因素都可能影响输出,例如指令/更新的顺序等。祝好! - Nikos M.
好的,这是代码的输出: [link(http://www.awesomescreenshot.com/image/280400/3bdc1268d1e0a3ff96e8bd0534a01969) - Zaay
为了这个问题创建了聊天室在这里,加入讨论吧。 - Nikos M.
显示剩余3条评论

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