nml::quat nml::rotationMatrixToQuat(const nml::mat4& mat)

Return a quaternion from a rotation matrix.

The conversion from a rotation matrix to a quaternion is calculated this way:

\(trace = mat.x.x + mat.y.y + mat.z.z\)

if

\(trace \gt 0\)

\(S = \sqrt{1 + trace} * 2\)

\(quat.a = \frac{S}{4}\)

\(quat.b = \frac{mat.y.z - mat.z.y}{S}\)

\(quat.c = \frac{mat.z.x - mat.x.z}{S}\)

\(quat.d = \frac{mat.x.y - mat.y.x}{S}\)

else if

\((mat.x.x \gt mat.y.y) \&\& (mat.x.x \gt mat.z.z)\)

\(S = \sqrt{1 + mat.x.x - mat.y.y - mat.z.z} * 2\)

\(quat.a = \frac{mat.y.z - mat.z.y}{S}\)

\(quat.b = \frac{S}{4}\)

\(quat.c = \frac{mat.y.x + mat.x.y}{S}\)

\(quat.d = \frac{mat.z.x + mat.x.z}{S}\)

else if

\((mat.y.y \gt mat.z.z)\)

\(S = \sqrt{1 + mat.x.x - mat.y.y - mat.z.z} * 2\)

\(quat.a = \frac{mat.z.x - mat.x.z}{S}\)

\(quat.b = \frac{mat.y.x + mat.x.y}{S}\)

\(quat.c = \frac{S}{4}\)

\(quat.d = \frac{mat.z.y + mat.y.z}{S}\)

else

\(S = \sqrt{1 + mat.z.z - mat.x.x - mat.y.y} * 2\)

\(quat.a = \frac{mat.x.y - mat.y.x}{S}\)

\(quat.b = \frac{mat.z.x + mat.x.z}{S}\)

\(quat.c = \frac{mat.z.y + mat.y.z}{S}\)

\(quat.d = \frac{S}{4}\)

Example

#include "include/quat.h"
#include "include/mat4.h"
#include <iostream>

int main() {
        nml::mat4 m(-1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);
        nml::quat q = nml::rotationMatrixToQuat(m);
        std::cout << nml::to_string(q) << std::endl;

        return 0;
}

Result:

0.000000 + 0.000000i + 1.000000j + 0.000000k