mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-01 09:42:01 +08:00
Fix poor Quaternion::slerp snapping
This commit is contained in:
parent
ea684af6b4
commit
c68c695b87
@ -583,20 +583,29 @@ template <class OtherDerived>
|
|||||||
Quaternion<typename ei_traits<Derived>::Scalar>
|
Quaternion<typename ei_traits<Derived>::Scalar>
|
||||||
QuaternionBase<Derived>::slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const
|
QuaternionBase<Derived>::slerp(Scalar t, const QuaternionBase<OtherDerived>& other) const
|
||||||
{
|
{
|
||||||
static const Scalar one = Scalar(1) - dummy_precision<Scalar>();
|
static const Scalar one = Scalar(1) - epsilon<Scalar>();
|
||||||
Scalar d = this->dot(other);
|
Scalar d = this->dot(other);
|
||||||
Scalar absD = ei_abs(d);
|
Scalar absD = ei_abs(d);
|
||||||
|
|
||||||
|
Scalar scale0;
|
||||||
|
Scalar scale1;
|
||||||
|
|
||||||
if (absD>=one)
|
if (absD>=one)
|
||||||
return Quaternion<Scalar>(derived());
|
{
|
||||||
|
scale0 = Scalar(1) - t;
|
||||||
|
scale1 = t;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// theta is the angle between the 2 quaternions
|
||||||
|
Scalar theta = std::acos(absD);
|
||||||
|
Scalar sinTheta = ei_sin(theta);
|
||||||
|
|
||||||
// theta is the angle between the 2 quaternions
|
scale0 = ei_sin( ( Scalar(1) - t ) * theta) / sinTheta;
|
||||||
Scalar theta = std::acos(absD);
|
scale1 = ei_sin( ( t * theta) ) / sinTheta;
|
||||||
Scalar sinTheta = ei_sin(theta);
|
if (d<0)
|
||||||
|
scale1 = -scale1;
|
||||||
Scalar scale0 = ei_sin( ( Scalar(1) - t ) * theta) / sinTheta;
|
}
|
||||||
Scalar scale1 = ei_sin( ( t * theta) ) / sinTheta;
|
|
||||||
if (d<0)
|
|
||||||
scale1 = -scale1;
|
|
||||||
|
|
||||||
return Quaternion<Scalar>(scale0 * coeffs() + scale1 * other.coeffs());
|
return Quaternion<Scalar>(scale0 * coeffs() + scale1 * other.coeffs());
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user