Я хотел бы построить поверх этого вопроса о вращении объекта по направлению к конкретной цели с кватернионами. Мой конкретный вариант использования будет состоять в том, чтобы ориентировать соединение в трехмерном пространстве в направлении другой или целевой точки, в качестве трамплина для реализации обратной кинематики.
Я использую 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
), небольшие изменения угла (небольшие сдвиги целевого объекта) приводят к экстремальным изменениям ориентации исходного объекта.
Мой вопрос: почему это происходит и что мы можем сделать, чтобы ослабить этот эффект?