Math Lib: signed versions of quaternion angle
There was no simple way to get the shortest quaternion angle.
This commit is contained in:
parent
bb30ce0f0b
commit
7a58ff928c
Notes:
blender-bot
2023-02-14 06:17:15 +01:00
Referenced by issue #53683, 2.79a release
|
@ -97,6 +97,11 @@ float angle_normalized_qtqt(const float q1[4], const float q2[4]);
|
|||
float angle_qt(const float q[4]);
|
||||
float angle_qtqt(const float q1[4], const float q2[4]);
|
||||
|
||||
float angle_signed_normalized_qt(const float q[4]);
|
||||
float angle_signed_normalized_qtqt(const float q1[4], const float q2[4]);
|
||||
float angle_signed_qt(const float q[4]);
|
||||
float angle_signed_qtqt(const float q1[4], const float q2[4]);
|
||||
|
||||
/* TODO: don't what this is, but it's not the same as mat3_to_quat */
|
||||
void mat3_to_quat_is_ok(float q[4], float mat[3][3]);
|
||||
|
||||
|
|
|
@ -511,6 +511,14 @@ void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q
|
|||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Quaternion Angle
|
||||
*
|
||||
* Unlike the angle between vectors, this does NOT return the shortest angle.
|
||||
* See signed functions below for this.
|
||||
*
|
||||
* \{ */
|
||||
|
||||
float angle_normalized_qt(const float q[4])
|
||||
{
|
||||
BLI_ASSERT_UNIT_QUAT(q);
|
||||
|
@ -548,6 +556,64 @@ float angle_qtqt(const float q1[4], const float q2[4])
|
|||
return angle_normalized_qtqt(quat1, quat2);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Quaternion Angle (Signed)
|
||||
*
|
||||
* Angles with quaternion calculation can exceed 180d,
|
||||
* Having signed versions of these functions allows 'fabsf(angle_signed_qtqt(...))'
|
||||
* to give us the shortest angle between quaternions.
|
||||
* With higher precision than subtracting pi afterwards.
|
||||
*
|
||||
* \{ */
|
||||
|
||||
float angle_signed_normalized_qt(const float q[4])
|
||||
{
|
||||
BLI_ASSERT_UNIT_QUAT(q);
|
||||
if (q[0] >= 0.0f) {
|
||||
return 2.0f * saacos(q[0]);
|
||||
}
|
||||
else {
|
||||
return -2.0f * saacos(-q[0]);
|
||||
}
|
||||
}
|
||||
|
||||
float angle_signed_normalized_qtqt(const float q1[4], const float q2[4])
|
||||
{
|
||||
if (dot_qtqt(q1, q2) >= 0.0f) {
|
||||
return angle_normalized_qtqt(q1, q2);
|
||||
}
|
||||
else {
|
||||
float q2_copy[4];
|
||||
negate_v4_v4(q2_copy, q2);
|
||||
return -angle_normalized_qtqt(q1, q2_copy);
|
||||
}
|
||||
}
|
||||
|
||||
float angle_signed_qt(const float q[4])
|
||||
{
|
||||
float tquat[4];
|
||||
|
||||
normalize_qt_qt(tquat, q);
|
||||
|
||||
return angle_signed_normalized_qt(tquat);
|
||||
}
|
||||
|
||||
float angle_signed_qtqt(const float q1[4], const float q2[4])
|
||||
{
|
||||
if (dot_qtqt(q1, q2) >= 0.0f) {
|
||||
return angle_qtqt(q1, q2);
|
||||
}
|
||||
else {
|
||||
float q2_copy[4];
|
||||
negate_v4_v4(q2_copy, q2);
|
||||
return -angle_qtqt(q1, q2_copy);
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
void vec_to_quat(float q[4], const float vec[3], short axis, const short upflag)
|
||||
{
|
||||
const float eps = 1e-4f;
|
||||
|
|
Loading…
Reference in New Issue