依次围绕世界轴旋转 threejs 对象(外部欧拉角)
Sequentially rotate threejs object around world axes (extrinsic Euler angles)
我正在创建外部欧拉角旋转的可视化,我想要一个立方体根据用户输入围绕世界轴旋转的动画。我有一个带有 x、y 和 z 旋转角度控件的 dat.GUI 控件。
See this screenshot.
到目前为止,我已经能够实现 内部 旋转,只需使用 cube_axes.rotation.x
(和 .y
、.z
)并设置立方体旋转。我的 GUI 代码如下所示:
gui.add(params, 'x_rot').name('X rotation').min(-180).max(180).step(5).onChange(() => {
cube_axes.rotation.x = toRadians(params.x_rot)
})
gui.add(params, 'y_rot').name('Y rotation').min(-180).max(180).step(5).onChange(() => {
cube_axes.rotation.y = toRadians(params.y_rot)
})
gui.add(params, 'z_rot').name('Z rotation').min(-180).max(180).step(5).onChange(() => {
cube_axes.rotation.z = toRadians(params.z_rot)
})
当用户移动 x 旋转控件时,立方体将围绕其局部 x 轴旋转指定的度数。然后,当用户移动 y 旋转控件时,already-rotated 立方体围绕其局部 y 轴旋转。
然而,我在 外部 旋转时遇到的问题是,立方体会擦除以前的旋转(本质上是自我重置)并简单地旋转正在更改的控件。因此,立方体永远不会在之前的旋转之上旋转。这是我的代码:
gui.add(params, 'x_rot').name('X rotation').min(-180).max(180).step(5).onChange(() => {
//cube_axes.setRotationFromAxisAngle(x_vector, toRadians(params.x_rot))
let quaternion = new THREE.Quaternion().setFromAxisAngle(x_vector, toRadians(params.x_rot));
cube_axes.rotation.setFromQuaternion(quaternion);
})
gui.add(params, 'y_rot').name('Y rotation').min(-180).max(180).step(5).onChange(() => {
//cube_axes.setRotationFromAxisAngle(y_vector, toRadians(params.y_rot))
let quaternion = new THREE.Quaternion().setFromAxisAngle(y_vector, toRadians(params.y_rot));
cube_axes.rotation.setFromQuaternion(quaternion);
})
gui.add(params, 'z_rot').name('Z rotation').min(-180).max(180).step(5).onChange(() => {
//cube_axes.setRotationFromAxisAngle(z_vector, toRadians(params.z_rot))
let quaternion = new THREE.Quaternion().setFromAxisAngle(z_vector, toRadians(params.z_rot));
cube_axes.rotation.setFromQuaternion(quaternion);
})
我试过使用 .setFromQuaternion
(来自 this question)和 .setRotationFromAxisAngle
(注释掉的行),但两种方法都有同样的问题。我不确定这里发生了什么。是因为我使用 .rotation
而不是特定的旋转轴(.rotation.x
、.rotation.y
、.rotation.z
)吗?
谢谢。
我明白了!使用 .applyQuaternion
而不是 .setFromQuaternion
。根据我的理解,这在已经存在的内容之上应用了旋转,而不是完全重置它。这是我的代码:
gui.add(params, 'x_rot').name('X rotation').min(-180).max(180).step(5).onChange(() => {
let quaternion = new THREE.Quaternion().setFromAxisAngle(x_vector, toRadians(params.x_rot));
cube_axes.applyQuaternion(quaternion);
})
gui.add(params, 'y_rot').name('Y rotation').min(-180).max(180).step(5).onChange(() => {
let quaternion = new THREE.Quaternion().setFromAxisAngle(y_vector, toRadians(params.y_rot));
cube_axes.applyQuaternion(quaternion);
})
gui.add(params, 'z_rot').name('Z rotation').min(-180).max(180).step(5).onChange(() => {
let quaternion = new THREE.Quaternion().setFromAxisAngle(z_vector, toRadians(params.z_rot));
cube_axes.applyQuaternion(quaternion);
})
请注意,此实现不使用三个对象的 rotation
属性。
编辑:对于那些试图做同样事情的人,您还需要一个额外的变量来跟踪先前的参数,以便您可以应用正确的角度。否则,您最终会得到不正确的旋转(只要控件发生变化,旋转就会继续添加另一个角度)。
请看下面的代码:
let prev_params = {
x_rot: 0,
y_rot: 0,
z_rot: 0,
}
然后 GUI onChange 函数中的这段代码(我只包含了 x 的代码):
let angle = toRadians(params.x_rot)
if (prev_params.x_rot) {
angle = angle - toRadians(prev_params.x_rot)
}
let quaternion = new THREE.Quaternion().setFromAxisAngle(x_vector, angle)
cube_axes.applyQuaternion(quaternion)
prev_params.x_rot = params.x_rot
我正在创建外部欧拉角旋转的可视化,我想要一个立方体根据用户输入围绕世界轴旋转的动画。我有一个带有 x、y 和 z 旋转角度控件的 dat.GUI 控件。 See this screenshot.
到目前为止,我已经能够实现 内部 旋转,只需使用 cube_axes.rotation.x
(和 .y
、.z
)并设置立方体旋转。我的 GUI 代码如下所示:
gui.add(params, 'x_rot').name('X rotation').min(-180).max(180).step(5).onChange(() => {
cube_axes.rotation.x = toRadians(params.x_rot)
})
gui.add(params, 'y_rot').name('Y rotation').min(-180).max(180).step(5).onChange(() => {
cube_axes.rotation.y = toRadians(params.y_rot)
})
gui.add(params, 'z_rot').name('Z rotation').min(-180).max(180).step(5).onChange(() => {
cube_axes.rotation.z = toRadians(params.z_rot)
})
当用户移动 x 旋转控件时,立方体将围绕其局部 x 轴旋转指定的度数。然后,当用户移动 y 旋转控件时,already-rotated 立方体围绕其局部 y 轴旋转。
然而,我在 外部 旋转时遇到的问题是,立方体会擦除以前的旋转(本质上是自我重置)并简单地旋转正在更改的控件。因此,立方体永远不会在之前的旋转之上旋转。这是我的代码:
gui.add(params, 'x_rot').name('X rotation').min(-180).max(180).step(5).onChange(() => {
//cube_axes.setRotationFromAxisAngle(x_vector, toRadians(params.x_rot))
let quaternion = new THREE.Quaternion().setFromAxisAngle(x_vector, toRadians(params.x_rot));
cube_axes.rotation.setFromQuaternion(quaternion);
})
gui.add(params, 'y_rot').name('Y rotation').min(-180).max(180).step(5).onChange(() => {
//cube_axes.setRotationFromAxisAngle(y_vector, toRadians(params.y_rot))
let quaternion = new THREE.Quaternion().setFromAxisAngle(y_vector, toRadians(params.y_rot));
cube_axes.rotation.setFromQuaternion(quaternion);
})
gui.add(params, 'z_rot').name('Z rotation').min(-180).max(180).step(5).onChange(() => {
//cube_axes.setRotationFromAxisAngle(z_vector, toRadians(params.z_rot))
let quaternion = new THREE.Quaternion().setFromAxisAngle(z_vector, toRadians(params.z_rot));
cube_axes.rotation.setFromQuaternion(quaternion);
})
我试过使用 .setFromQuaternion
(来自 this question)和 .setRotationFromAxisAngle
(注释掉的行),但两种方法都有同样的问题。我不确定这里发生了什么。是因为我使用 .rotation
而不是特定的旋转轴(.rotation.x
、.rotation.y
、.rotation.z
)吗?
谢谢。
我明白了!使用 .applyQuaternion
而不是 .setFromQuaternion
。根据我的理解,这在已经存在的内容之上应用了旋转,而不是完全重置它。这是我的代码:
gui.add(params, 'x_rot').name('X rotation').min(-180).max(180).step(5).onChange(() => {
let quaternion = new THREE.Quaternion().setFromAxisAngle(x_vector, toRadians(params.x_rot));
cube_axes.applyQuaternion(quaternion);
})
gui.add(params, 'y_rot').name('Y rotation').min(-180).max(180).step(5).onChange(() => {
let quaternion = new THREE.Quaternion().setFromAxisAngle(y_vector, toRadians(params.y_rot));
cube_axes.applyQuaternion(quaternion);
})
gui.add(params, 'z_rot').name('Z rotation').min(-180).max(180).step(5).onChange(() => {
let quaternion = new THREE.Quaternion().setFromAxisAngle(z_vector, toRadians(params.z_rot));
cube_axes.applyQuaternion(quaternion);
})
请注意,此实现不使用三个对象的 rotation
属性。
编辑:对于那些试图做同样事情的人,您还需要一个额外的变量来跟踪先前的参数,以便您可以应用正确的角度。否则,您最终会得到不正确的旋转(只要控件发生变化,旋转就会继续添加另一个角度)。 请看下面的代码:
let prev_params = {
x_rot: 0,
y_rot: 0,
z_rot: 0,
}
然后 GUI onChange 函数中的这段代码(我只包含了 x 的代码):
let angle = toRadians(params.x_rot)
if (prev_params.x_rot) {
angle = angle - toRadians(prev_params.x_rot)
}
let quaternion = new THREE.Quaternion().setFromAxisAngle(x_vector, angle)
cube_axes.applyQuaternion(quaternion)
prev_params.x_rot = params.x_rot