在Three.js中围绕一个点旋转对象的正确方法是什么?

Chr*_*ris 10 javascript three.js

大多数关于three.js的教程/问题都建议使用Three.js围绕对象旋转对象的方法是在要旋转的位置创建父对象,附加对象,然后移动子对象。然后,当父母旋转时,孩子绕该点旋转。例如;

//Make a pivot
var pivot = new THREE.Object3D();
//Make an object
var object = new THREE.Mesh( new THREE.BoxGeometry(2,2,2), new THREE.MeshBasicMaterial() );
//Add object to pivot
pivot.add(object);

//Move object away from pivot
object.position.set(new THREE.Vector3(5,0,0));

//rotate the object 90 degrees around pivot
pivot.rotation.y = Math.PI / 2;
Run Code Online (Sandbox Code Playgroud)

这行得通,但它的局限性令人难以置信-如果您想围绕另一个点旋转对象,则不能这样做,因为一个对象不能有两个父对象。

下一个可行的方法是将旋转矩阵应用于对象的位置,例如:

//Make an object
var object = new THREE.Mesh( new THREE.BoxGeometry(2,2,2), new THREE.MeshBasicMaterial() );
//Move the object
object.position.set(new THREE.Vector3(5,0,0);

//Create a matrix
var matrix = new THREE.Matrix4();
//Rotate the matrix
matrix.makeRotationY(Math.PI / 2);

//rotate the object using the matrix
object.position.applyMatrix4(matrix);
Run Code Online (Sandbox Code Playgroud)

同样,这可行,但是似乎没有设置旋转点的方法。它永远是世界的起源。

另一个选项是sceneUtils中的实用程序方法,用于将子对象与父对象分离,另一种方法是附加新的父对象,但是该文档警告不要使用它,并且在任何示例代码中都从未使用过。

最终,我希望能够使多维数据集遵循S形路径,但是如果没有这个(貌似)基本的东西,我会发现它相当困难。

tl; dr我想围绕一系列不同的点旋转three.js对象。什么是解决这个问题的好方法?

Sum*_*Sun 8

简单的解决方案:移动到锚点,旋转,然后向后移动。

假设您想要camera围绕 an旋转 a anchorPoint(camera是 的实例THREE.Camera并且anchorPoint是 here 的实例THREE.Vector3):

/// step 1: calculate move direction and move distance:
let moveDir = new THREE.Vector3(
    anchorPoint.x - camera.position.x,
    anchorPoint.y - camera.position.y,
    anchorPoint.z - camera.position.z
);
moveDir.normalize();
let moveDist = camera.position.distanceTo(anchorPoint);
/// step 2: move camera to anchor point
camera.translateOnAxis(moveDir, moveDist);
/// step 3: rotate camera
camera.rotateX(valX);
camera.rotateY(valY);
camera.rotateZ(valZ);
/// step4: move camera along the opposite direction
moveDir.multiplyScalar(-1);
camera.translateOnAxis(moveDir, moveDist);
Run Code Online (Sandbox Code Playgroud)


The*_*m01 7

这个答案可能会有所帮助:三个 JS Pivot point

有几种方法可以解决这个问题。正如您所提到的,您可以在育儿方法中交换枢轴点,但需要大量工作,将对象位置转换为不同的坐标系/从不同的坐标系转换。

相反,您始终可以这样看待它(伪代码):

  1. 将对象移动到枢轴点

    1.1. 从对象的原始位置减去枢轴点

  2. 应用您的轮换

  3. 将对象向后移动相同的位置向量

    1.1. 将枢轴点添加到对象的位置

注意:一切都在世界坐标系中,因此您可能需要进行适当的转换。