逐分量运算 Component Wise Operations

整理四元数加减、数乘、取反和比较等逐分量操作。

逐分量运算 Component Wise Operations

四元数的逐分量运算通常会改变其长度,使其不再是单位长度,所以进行过运算以后需要进行归一化

加法,减法,数乘

Quaternion Add(Quaternion left, Quaternion right) {
    return Quaternion(
        left.x + right.x,
        left.y + right.y,
        left.z + right.z,
        left.w + right.w
    );
}
 
Quaternion Subtract(Quaternion left, Quaternion right) {
    return Quaternion(
        left.x - right.x,
        left.y - right.y,
        left.z - right.z,
        left.w - right.w
    );
}
 
Quaternion Scale(Quaternion quat, float scalar) {
    return Quaternion(
        quat.x * scalar,
        quat.y * scalar,
        quat.z * scalar,
        quat.w * scalar
    );
}

取反 Negation

注意这和四元数的 不同,取反的四元数执行与其正数对应相同的旋转,这是因为在取反四元数时,旋转轴和旋转角度都会翻转

Quaternion Negate(Quaternion quat) {
    return Quaternion(
        quat.x * -1.0f,
        quat.y * -1.0f,
        quat.z * -1.0f,
        quat.w * -1.0f
    );
}

比较 Comparison

由于四元数和它的负数表示相同的旋转,所以要比较两个四元数是否相同,我们需要逐个分量比较四元数以及其相反数

bool Same(Quaternion left, Quaternion right) {
    return (abs(left.x - right.x) <= EPSILON && abs(left.y - right.y) <= EPSILON && abs(left.z - right.z) <= EPSILON && abs(left.w - left.w) <= EPSILON)
        || (abs(left.x + right.x) <= EPSILON && abs(left.y + right.y) <= EPSILON && abs(left.z + right.z) <= EPSILON && abs(left.w + left.w) <= EPSILON);
}

仅比较四元数而不比较其相反数也有意义,即查看四元数自身是否发生改变

bool Equals(Quaternion left, Quaternion right) {
    return (abs(left.x - right.x) <= EPSILON && abs(left.y - right.y) <= EPSILON && abs(left.z - right.z) <= EPSILON && abs(left.w - left.w) <= EPSILON);
}