我正在尝试建模一个魔方的个人项目,使用泽德轻量级3d图形。Zdog使用一个{x,y,z}向量来表示旋转--我相信这本质上是一个泰特-布莱恩角。

为了动画的顶部,右边,正面等的旋转,我把这9个街区连接到一个锚点在立方体的中心,并旋转它90度,以所需的方向。这是很好的工作,但当动画完成后,我需要“保存”在9个块上的平移和旋转。翻译是相对简单的,但我只能坚持旋转。我基本上需要这样的功能:
function updateRotation(xyz, axis, angle) {
// xyz is a {x,y,z} vector
// axis is "x", "y", or "z"
// rotation is the angle of rotation in radians
}这将将世界坐标中的axis/angle旋转应用于对象坐标中的xyz向量。最初我只有xyz[axis] += angle,但只有当没有其他轴有任何旋转时,这才能工作。然后我想我可以使用一个查找表,我认为这是可能的,因为我只使用四分之一圈,但是构建这个表比我想象的要困难。
我开始怀疑我需要将xyz向量转换成其他的表示(矩阵)?四元数?)然后在那里进行旋转,但我不知道从哪里开始。令人沮丧的是,我的块在动画的末尾处于正确的位置--我只是不知道如何应用父转换,这样我就可以在不失去旋转的情况下将它们从父块中分离出来。
发布于 2022-05-11 23:12:58
据我所知,这不能仅用Euler角来完成(至少不是以任何简单的方式)。我的解决方案是转换为四元数,旋转,然后转换回欧拉:
function updateRotation(obj, axis, rotation) {
const {x, y, z} = obj.rotate;
const q = new Quaternion()
.rotateZ(z)
.rotateY(y)
.rotateX(x);
const q2 = new Quaternion();
if (axis === 'x') {
q2.rotateX(rotation);
} else if (axis === 'y') {
q2.rotateY(rotation);
} else if (axis === 'z') {
q2.rotateZ(rotation);
}
q.multiply(q2, null);
const e = new Euler().fromQuaternion(q);
obj.rotate.x = e.x;
obj.rotate.y = e.y;
obj.rotate.z = e.z;
obj.normalizeRotate();
}这使用了来自Euler和Quaternion的math.gl类。
(据我所知,Zdog实际上使用了ZYX欧拉角,因此在创建第一个四元数时使用旋转的顺序。)
https://stackoverflow.com/questions/72021357
复制相似问题