Siyuan Fu

Avater

send mail Github Linkedin orcid Twitter

Transforms

Homogeneous Matrices

Right handed coordinate. Counterclockwise rotation.

Global transformations are pre-multiply.

Local transformations are post-multiply.

To transform from right handed to left handed, simply reverse the z-axis component.

Quaternion

, where is angle, is axis.

Denote by , by :

To rotate a vector by quaternion :

To convert a rotation matrix to quaternion (assume mat3 is row-major):

double tmp = rot[0][0] + rot[1][1] + rot[2][2];
if (tmp <= -1.0) {
    if ((rot[0][0] > rot[1][1]) && (rot[0][0] > rot[2][2])) {
        V.x = sqrt(1.0 + rot[0][0] - rot[1][1] - rot[2][2]) * 0.5;
        S = (rot[2][1] - rot[1][2]) / V.x * 0.25;
        V.y = (rot[0][1] + rot[1][0]) / V.x * 0.25;
        V.z = (rot[0][2] + rot[2][0]) / V.x * 0.25;
    }
    else if (rot[1][1] > rot[2][2]) {
        V.y = sqrt(1.0 + rot[1][1] - rot[0][0] - rot[2][2]) * 0.5;
        S = (rot[0][2] - rot[2][0]) / V.y * 0.25;
        V.x = (rot[0][1] + rot[1][0]) / V.y * 0.25;
        V.z = (rot[1][2] + rot[2][1]) / V.y * 0.25;
    }
    else {
        V.z = sqrt(1.0 + rot[2][2] - rot[0][0] - rot[1][1]) * 0.5;
        S = (rot[1][0] - rot[0][1]) / V.z * 0.25;
        V.x = (rot[0][2] + rot[2][0]) / V.z * 0.25;
        V.y = (rot[1][2] + rot[2][1]) / V.z * 0.25;
    }
}
else {
    S = 0.5 * sqrt(1 + tmp);
    V.x = (rot[2][1]-rot[1][2]) / S * 0.25;
    V.y = (rot[0][2]-rot[2][0]) / S * 0.25;
    V.z = (rot[1][0]-rot[0][1]]) / mQ[VW] * 0.25;
}

To convert a quaternion to rotation matrix:

mat3 m;
m.Identity();
double w = S;
double x = V.x;
double y = V.y;
double z = V.z;
m[0][0] = 1 - 2 * y * y - 2 * z * z;
m[0][1] = 2 * x * y - 2 * w * z;
m[0][2] = 2 * x * z + 2 * w * y;
m[1][0] = 2 * x * y + 2 * w * z;
m[1][1] = 1 - 2 * x * x - 2 * z * z;
m[1][2] = 2 * y * z - 2 * w * x;
m[2][0] = 2 * x * z - 2 * w * y;
m[2][1] = 2 * y * z + 2 * w * x;
m[2][2] = 1 - 2 * x * x - 2 * y * y;
return m;

Interpolation

SDouble

SBisect

Slerp

quat o;
quat p = q0, q = q1;
double cosine = Dot(p, q);
if (cosine == 1) {
    o = (1 - u) * p + u * q;
    return o.Normalize();
}
if (cosine < 0) {
    p = -p;
    cosine = -cosine;
}
double sine = sqrt(1 - cosine * cosine);
double theta = acos(cosine);
o = (sin((1 - u) * theta) * p + sin(u * theta) * q) / sine;
return o.Normalize();
tags: Graphics