49 constexpr real kDotThreshold = 1e-6_r;
60 if (dot < 1_r - kDotThreshold)
62 dot =
Clamp(dot, -1.0_r, 1.0_r);
95 real t = 0.5_r * (matrix[0][0] + matrix[1][1] + matrix[2][2] - 1_r);
102 axis = {1_r, 0_r, 0_r};
108 real xx = (matrix[0][0] + 1_r) * 0.5_r;
109 real yy = (matrix[1][1] + 1_r) * 0.5_r;
110 real zz = (matrix[2][2] + 1_r) * 0.5_r;
111 real xy = (matrix[0][1] + matrix[1][0]) * 0.25_r;
112 real xz = (matrix[0][2] + matrix[2][0]) * 0.25_r;
113 real yz = (matrix[1][2] + matrix[2][1]) * 0.25_r;
115 if ((xx > yy) && (xx > zz)) {
117 axis =
Real3{0_r, kSqrt2Over2, kSqrt2Over2};
120 axis =
Real3{x, xy / x, xz / x};
122 }
else if (yy > zz) {
124 axis =
Real3{kSqrt2Over2, 0_r, kSqrt2Over2};
127 axis =
Real3{xy / y, y, yz / y};
131 axis =
Real3{kSqrt2Over2, kSqrt2Over2, 0_r};
134 axis =
Real3{xz / z, yz / z, z};
140 real scale = 0.5_r /
Sin(theta);
142 (matrix[2][1] - matrix[1][2]) * scale,
143 (matrix[0][2] - matrix[2][0]) * scale,
144 (matrix[1][0] - matrix[0][1]) * scale};
148 return Real4{axis[0], axis[1], axis[2], theta};
153 Real4 const axisAngle = superdex::details::MatrixToAxisAngleImpl(matrix, eps);
154 Real3 const axis{axisAngle[0], axisAngle[1], axisAngle[2]};
155 real const angle = axisAngle[3];
Quaternion GetConjugate() const
static Quaternion FromAxisAngle(Vec4r axis, real angleRadians)
T Dot(Simd< T, N > a, Simd< T, N > b)
Quaternion Slerp(Quaternion a, Quaternion b, real t)
Simd< T, N > VIsFinite(Simd< T, N > a)
T NormSqr(Simd< T, N > a)
Matrix3x3r ToMatrix3x3(Quaternion const &q)
NdArray< Simd< real, 4 >, 3 > VMatrix3x3r
NdArray< T, 3, 3 > ToNdArray3x3(NdArray< Simd< T, 4 >, 3 > m)
NdArray< Simd< T, 4 >, 3 > Transpose3x3(NdArray< Simd< T, 4 >, D0 > const &m)
Simd< T, N > Normalize(Simd< T, N > a)
constexpr NdArray< T, D0, DIMS... > operator/(NdArray< T, D0, DIMS... > const &lhs, NdArray< T, D0, DIMS... > const &rhs)
Quaternion Conjugate(Quaternion const &a)
VMatrix3x3r ToVMatrix3x3Transpose(Quaternion const &q)
constexpr NdArray< T, D0, DIMS... > operator*(NdArray< T, D0, DIMS... > const &lhs, NdArray< T, D0, DIMS... > const &rhs)
constexpr ValT Clamp(ValT value, MinT min, MaxT max)
VMatrix3x3r ToVMatrix3x3(Quaternion const &q)
constexpr T Lerp(T a, T b, Frac t)
NdArray< real, 3, 3 > Matrix3x3r
bool NearEqual(TransformRT const &a, TransformRT const &b, real epsilon=kDefaultNearEqualEpsilon< real >)
std::pair< VMatrix3x3r, VMatrix3x3r > ToVMatrix3x3_WithTranspose(Quaternion const &q)
Quaternion QuaternionFromMatrix(VMatrix3x3r const &matrix, real eps=1e-3_r)
bool IsFinite(TransformRT const &a)
bool EquivalentRotation(Quaternion const &a, Quaternion const &b, Vec4r epsilon)