约束3D旋转的正确/最佳方法是什么(使用欧拉角和/或四元数)?
我的做法似乎有些不对劲.我正在将旋转应用于骨架层次结构中的骨骼以进行动画,并且骨骼有时会明显地"跳"到错误的方向,并且各个Euler组件正在环绕其范围的另一端.
我使用欧拉角来表示当前方向,转换为四元数来进行旋转,并独立地夹住每个欧拉角轴.这是C++伪代码,基本上显示了我正在做的事情:
Euler min = ...;
Euler max = ...;
Quat rotation = ...;
Euler eCurrent = ...;
// do rotation
Quat qCurrent = eCurrent.toQuat();
qCurrent = qCurrent * rotation;
eCurrent = qCurrent.toEuler();
// constrain
for (unsigned int i = 0; i < 3; i++)
eCurrent[i] = clamp(eCurrent[i], min[i], max[i]);
Run Code Online (Sandbox Code Playgroud)
小智 0
这里的问题是您应用的约束与应用的旋转无关。从概念的角度来看,这就是您想要实现的目标:
限制欧拉旋转的代码是您将骨骼旋转回来的部分。但是,此代码忽略了原始骨骼旋转,因此您会看到奇怪的行为,例如您所看到的捕捉。
处理这个问题的一个简单方法是这样做:
现在这将起作用,但由于您的旋转四元数应用于所有角度,因此当这些约束中的任何一个为净值时,即使其他地方存在自由度,旋转也会停止。
相反,如果您彼此独立地应用旋转,那么您将能够可靠地使用夹紧或上述技术来遵守约束,并且还可以尽可能接近目标进行旋转。- -