두 쿼터니언 사이의 Slerp 보간 방법에 대한 두 가지 다른 소스를보고 있습니다. 그들은 하나 개의 주목할만한 차이를 제외하고 꽤 비슷 하나는 0과 1, 그리고 Here -1과 1 사이 다른 사이의 내적을 클램프 그들 중 하나입니다 : 여기 Quaternion 용 Slerp에서 내 제품 클램프
glm::fquat Slerp(const glm::fquat &v0, const glm::fquat &v1, float alpha)
{
float dot = glm::dot(v0, v1);
const float DOT_THRESHOLD = 0.9995f;
if (dot > DOT_THRESHOLD)
return Lerp(v0, v1, alpha);
glm::clamp(dot, -1.0f, 1.0f); //<-- The line in question
float theta_0 = acosf(dot);
float theta = theta_0*alpha;
glm::fquat v2 = v1 - v0*dot;
v2 = glm::normalize(v2);
return v0*cos(theta) + v2*sin(theta);
}
다른입니다 :
template <typename T>
inline QuaternionT<T> QuaternionT<T>::Slerp(T t, const QuaternionT<T>& v1) const
{
const T epsilon = 0.0005f;
T dot = Dot(v1);
if (dot > 1 - epsilon) {
QuaternionT<T> result = v1 + (*this - v1).Scaled(t);
result.Normalize();
return result;
}
if (dot < 0) //<-The lower clamp
dot = 0;
if (dot > 1)
dot = 1;
T theta0 = std::acos(dot);
T theta = theta0 * t;
QuaternionT<T> v2 = (v1 - Scaled(dot));
v2.Normalize();
QuaternionT<T> q = Scaled(std::cos(theta)) + v2.Scaled(std::sin(theta));
q.Normalize();
return q;
}
두 번째 질문에서 Lerp
알고리즘이 모든 경우에 적합하지 않다고 생각합니다.
나는이 차이점에 대해 의견을 나누기를 바랍니다.
으로 잘 알려져있다. 두 번째 코드는 간단한 냄새 테스트를 통과하지 못합니다. 처음에는 1-eps를 확인한 다음 다시 1로 클램프합니다. 코드에서 수비가 좋을지라도 acos는 -1 또는 -1 + eps를 클램프해야하지만 0은 클램프하지 않아야합니다. – starmole