我想以此question为基础,将具有四元数的物体朝特定目标旋转。我的特殊用例是将3d空间中的关节定向到另一个或目标点,作为实现逆运动学的垫脚石。
我使用glm
数学库来计算点积和叉积。我还使用了其定义的结构vec3
和quat
。
以下是相关代码:
quat AxisAngleToQuat(float angle, vec3 axis) {
quat myquat = quat(cos(angle/2), axis.x*sin(angle/2), axis.y*sin(angle/2), axis.z*sin(angle/2));
return myquat;
}
vec3 direction = normalize(targetPos-sourcePos);
float dotProduct = dot(sourceForward, direction);
float angle = acos(dotProduct);
vec3 axis = normalize(cross(sourceForward, direction));
quat myquat;
//Handle special case where dotProduct is 1
if (Math.Abs(dotProduct-1.0f) < 0.000001f) {
myquat = quat(1, 0, 0, 0); //create identity quaternion
}
//Handle special case where dotProduct is -1
else if (Math.Abs(dotProduct+1.0f) < 0.000001f) {
vec3 arbitraryAxis = vec3(0, 1, 0); //we can choose global up as the arbitrary axis
myquat = AxisAngleToQuat((float)M_PI, arbitraryAxis);
}
else {
myquat = AxisAngleToQuat(angle, axis);
}
现在,在实现此功能并处理所有特殊情况之后,仍然存在问题。当angle
接近180
度时(我们接近源对象的原始后退方向-sourceForward
),角度的小变化(目标对象的小平移)会导致角度的极大变化。源对象方向。
我的问题是为什么会发生这种情况,我们该怎么做才能减弱这种影响?