diff options
author | Edward Welbourne <edward.welbourne@qt.io> | 2023-06-12 15:57:23 +0200 |
---|---|---|
committer | Edward Welbourne <edward.welbourne@qt.io> | 2023-08-18 18:39:14 +0200 |
commit | 820eff05f4ea934e11382ab32e318cb1fdd6954c (patch) | |
tree | a3095a53b62f9dcb9278024259cb396906807760 /src/gui/math3d | |
parent | 132be307fff049e83ba8b93733fc571c0c45469b (diff) |
Use atan2() in Quaternion axis-and-angle
It's more numerically robust than acos() - we can't hit a range error
if we get strange rounding effects - and we've got the value of the
sin of the angle already (it's the length of the x, y, z part), so
might as well use it. As length is necessarily positive, atan2() will
give an upper-half-plane resolution, matching what acos() gave us.
This incidentally means that you no longer need to normalize() your
quaternion before you ask for axis and angle.
Task-number: QTBUG-114313
Change-Id: If3fa2b371c72991f1f8f151f78ef7f9180aa87cf
Reviewed-by: Matthias Rauter <matthias.rauter@qt.io>
Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io>
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
Diffstat (limited to 'src/gui/math3d')
-rw-r--r-- | src/gui/math3d/qquaternion.cpp | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index 6998957ca1..f546d63a72 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -386,7 +386,7 @@ void QQuaternion::getAxisAndAngle(float *x, float *y, float *z, float *angle) co *y = yp / length; *z = zp / length; } - *angle = qRadiansToDegrees(2.0f * std::acos(wp)); + *angle = qRadiansToDegrees(2.0f * std::atan2(length, wp)); } else { // angle is 0 (mod 2*pi), so any axis will fit *x = *y = *z = *angle = 0.0f; |