Motor

group motor

A motor represents a kinematic motion in our algebra. From Chasles' theorem, we know that any rigid body displacement can be produced by a translation along a line, followed or preceded by a rotation about an axis parallel to that line. The motor algebra is isomorphic to the dual quaternions but exists here in the same algebra as all the other geometric entities and actions at our disposal. Operations such as composing a motor with a rotor or translator are possible for example. The primary benefit to using a motor over its corresponding matrix operation is twofold. First, you get the benefit of numerical stability when composing multiple actions via the geometric product (* ). Second, because the motors constitute a continuous group, they are amenable to smooth interpolation and differentiation.

Example

    // Create a rotor representing a pi/2 rotation about the z-axis
    // Normalization is done automatically
    rotor r{M_PI * 0.5f, 0.f, 0.f, 1.f};

    // Create a translator that represents a translation of 1 unit
    // in the yz-direction. Normalization is done automatically.
    translator t{1.f, 0.f, 1.f, 1.f};

    // Create a motor that combines the action of the rotation and
    // translation above.
    motor m = r * t;

    // Initialize a point at (1, 3, 2)
    kln::point p1{1.f, 3.f, 2.f};

    // Translate p1 and rotate it to create a new point p2
    kln::point p2 = m(p1);

Motors can be multiplied to one another with the * operator to create a new motor equivalent to the application of each factor.

Example

    // Suppose we have 3 motors m1, m2, and m3

    // The motor m created here represents the combined action of m1,
    // m2, and m3.
    kln::motor m = m3 * m2 * m1;

The same * operator can be used to compose the motor's action with other translators and rotors.

A demonstration of using the exponential and logarithmic map to blend between two motors is provided in a test case here.

Summary

Members Descriptions
public motor() = default
public motor(float a,float b,float c,float d,float e,float f,float g,float h) noexcept Direct initialization from components. A more common way of creating a motor is to take a product between a rotor and a translator. The arguments coorespond to the multivector \(a + b\mathbf{e}_{23} + c\mathbf{e}_{31} + d\mathbf{e}_{12} +\ e\mathbf{e}_{01} + f\mathbf{e}_{02} + g\mathbf{e}_{03} +\ h\mathbf{e}_{0123}\).
public motor(float ang_rad,float d,line l) noexcept Produce a screw motion rotating and translating by given amounts along a provided Euclidean axis.
public motor(__m128 p1,__m128 p2) noexcept
public KLN_VEC_CALL explicit motor(rotor r) noexcept
public KLN_VEC_CALL explicit motor(translator t) noexcept
public motor &KLN_VEC_CALL operator=(rotor r) noexcept
public motor &KLN_VEC_CALL operator=(translator t) noexcept
public void load(float * in) noexcept Load motor data using two unaligned loads. This routine does not assume the data passed in this way is normalized.
public void normalize() noexcept Normalizes this motor \(m\) such that \(m\widetilde{m} = 1\).
public motor normalized() const noexcept Return a normalized copy of this motor.
public void invert() noexcept
public motor inverse() const noexcept
public void constrain() noexcept Constrains the motor to traverse the shortest arc.
public motor constrained() const noexcept
public bool KLN_VEC_CALL operator==(motor other) const noexcept Bitwise comparison.
public bool KLN_VEC_CALL approx_eq(motor other,float epsilon) const noexcept
public mat3x4 as_mat3x4() const noexcept Convert this motor to a 3x4 column-major matrix representing this motor's action as a linear transformation. The motor must be normalized for this conversion to produce well-defined results, but is more efficient than a 4x4 matrix conversion.
public mat4x4 as_mat4x4() const noexcept Convert this motor to a 4x4 column-major matrix representing this motor's action as a linear transformation.
public plane KLN_VEC_CALL operator()(plane const & p) const noexcept Conjugates a plane \(p\) with this motor and returns the result \(mp\widetilde{m}\).
public void KLN_VEC_CALL operator()(plane * in,plane * out,size_t count) const noexcept Conjugates an array of planes with this motor in the input array and stores the result in the output array. Aliasing is only permitted when in == out (in place motor application).
public line KLN_VEC_CALL operator()(line const & l) const noexcept Conjugates a line \(\ell\) with this motor and returns the result \(m\ell \widetilde{m}\).
public void KLN_VEC_CALL operator()(line * in,line * out,size_t count) const noexcept Conjugates an array of lines with this motor in the input array and stores the result in the output array. Aliasing is only permitted when in == out (in place motor application).
public point KLN_VEC_CALL operator()(point const & p) const noexcept Conjugates a point \(p\) with this motor and returns the result \(mp\widetilde{m}\).
public void KLN_VEC_CALL operator()(point * in,point * out,size_t count) const noexcept Conjugates an array of points with this motor in the input array and stores the result in the output array. Aliasing is only permitted when in == out (in place motor application).
public point KLN_VEC_CALL operator()(origin) const noexcept Conjugates the origin \(O\) with this motor and returns the result \(mO\widetilde{m}\).
public direction KLN_VEC_CALL operator()(direction const & d) const noexcept Conjugates a direction \(d\) with this motor and returns the result \(md\widetilde{m}\).
public void KLN_VEC_CALL operator()(direction * in,direction * out,size_t count) const noexcept Conjugates an array of directions with this motor in the input array and stores the result in the output array. Aliasing is only permitted when in == out (in place motor application).
public motor &KLN_VEC_CALL operator+=(motor b) noexcept Motor addition.
public motor &KLN_VEC_CALL operator-=(motor b) noexcept Motor subtraction.
public motor & operator*=(float s) noexcept Motor uniform scale.
public motor & operator*=(int s) noexcept Motor uniform scale.
public motor & operator/=(float s) noexcept Motor uniform inverse scale.
public motor & operator/=(int s) noexcept Motor uniform inverse scale.
public float scalar() const noexcept
public float e12() const noexcept
public float e21() const noexcept
public float e31() const noexcept
public float e13() const noexcept
public float e23() const noexcept
public float e32() const noexcept
public float e01() const noexcept
public float e10() const noexcept
public float e02() const noexcept
public float e20() const noexcept
public float e03() const noexcept
public float e30() const noexcept
public float e0123() const noexcept
public motor KLN_VEC_CALL operator+(motor a,motor b) noexcept Motor addition.
public motor KLN_VEC_CALL operator-(motor a,motor b) noexcept Motor subtraction.
public motor KLN_VEC_CALL operator*(motor l,float s) noexcept Motor uniform scale.
public motor KLN_VEC_CALL operator*(motor l,int s) noexcept Motor uniform scale.
public motor KLN_VEC_CALL operator*(float s,motor l) noexcept Motor uniform scale.
public motor KLN_VEC_CALL operator*(int s,motor l) noexcept Motor uniform scale.
public motor KLN_VEC_CALL operator/(motor r,float s) noexcept Motor uniform inverse scale.
public motor KLN_VEC_CALL operator/(motor r,int s) noexcept Motor uniform inverse scale.
public motor KLN_VEC_CALL operator-(motor m) noexcept Unary minus.
public motor KLN_VEC_CALL operator~(motor m) noexcept Reversion operator.

Members

motor() = default

motor(float a,float b,float c,float d,float e,float f,float g,float h) noexcept

Direct initialization from components. A more common way of creating a motor is to take a product between a rotor and a translator. The arguments coorespond to the multivector \(a + b\mathbf{e}_{23} + c\mathbf{e}_{31} + d\mathbf{e}_{12} +\ e\mathbf{e}_{01} + f\mathbf{e}_{02} + g\mathbf{e}_{03} +\ h\mathbf{e}_{0123}\).

motor(float ang_rad,float d,line l) noexcept

Produce a screw motion rotating and translating by given amounts along a provided Euclidean axis.

motor(__m128 p1,__m128 p2) noexcept

KLN_VEC_CALL explicit motor(rotor r) noexcept

KLN_VEC_CALL explicit motor(translator t) noexcept

motor &KLN_VEC_CALL operator=(rotor r) noexcept

motor &KLN_VEC_CALL operator=(translator t) noexcept

void load(float * in) noexcept

Load motor data using two unaligned loads. This routine does not assume the data passed in this way is normalized.

void normalize() noexcept

Normalizes this motor \(m\) such that \(m\widetilde{m} = 1\).

motor normalized() const noexcept

Return a normalized copy of this motor.

void invert() noexcept

motor inverse() const noexcept

void constrain() noexcept

Constrains the motor to traverse the shortest arc.

motor constrained() const noexcept

bool KLN_VEC_CALL operator==(motor other) const noexcept

Bitwise comparison.

bool KLN_VEC_CALL approx_eq(motor other,float epsilon) const noexcept

mat3x4 as_mat3x4() const noexcept

Convert this motor to a 3x4 column-major matrix representing this motor's action as a linear transformation. The motor must be normalized for this conversion to produce well-defined results, but is more efficient than a 4x4 matrix conversion.

mat4x4 as_mat4x4() const noexcept

Convert this motor to a 4x4 column-major matrix representing this motor's action as a linear transformation.

plane KLN_VEC_CALL operator()(plane const & p) const noexcept

Conjugates a plane \(p\) with this motor and returns the result \(mp\widetilde{m}\).

void KLN_VEC_CALL operator()(plane * in,plane * out,size_t count) const noexcept

Conjugates an array of planes with this motor in the input array and stores the result in the output array. Aliasing is only permitted when in == out (in place motor application).

Tip

When applying a motor to a list of tightly packed planes, this routine will be significantly faster than applying the motor to each plane individually.

line KLN_VEC_CALL operator()(line const & l) const noexcept

Conjugates a line \(\ell\) with this motor and returns the result \(m\ell \widetilde{m}\).

void KLN_VEC_CALL operator()(line * in,line * out,size_t count) const noexcept

Conjugates an array of lines with this motor in the input array and stores the result in the output array. Aliasing is only permitted when in == out (in place motor application).

Tip

When applying a motor to a list of tightly packed lines, this routine will be significantly faster than applying the motor to each line individually.

point KLN_VEC_CALL operator()(point const & p) const noexcept

Conjugates a point \(p\) with this motor and returns the result \(mp\widetilde{m}\).

void KLN_VEC_CALL operator()(point * in,point * out,size_t count) const noexcept

Conjugates an array of points with this motor in the input array and stores the result in the output array. Aliasing is only permitted when in == out (in place motor application).

Tip

When applying a motor to a list of tightly packed points, this routine will be significantly faster than applying the motor to each point individually.

point KLN_VEC_CALL operator()(origin) const noexcept

Conjugates the origin \(O\) with this motor and returns the result \(mO\widetilde{m}\).

direction KLN_VEC_CALL operator()(direction const & d) const noexcept

Conjugates a direction \(d\) with this motor and returns the result \(md\widetilde{m}\).

The cost of this operation is the same as the application of a rotor due to the translational invariance of directions (points at infinity).

void KLN_VEC_CALL operator()(direction * in,direction * out,size_t count) const noexcept

Conjugates an array of directions with this motor in the input array and stores the result in the output array. Aliasing is only permitted when in == out (in place motor application).

The cost of this operation is the same as the application of a rotor due to the translational invariance of directions (points at infinity).

Tip

When applying a motor to a list of tightly packed directions, this routine will be significantly faster than applying the motor to each direction individually.

motor &KLN_VEC_CALL operator+=(motor b) noexcept

Motor addition.

motor &KLN_VEC_CALL operator-=(motor b) noexcept

Motor subtraction.

motor & operator*=(float s) noexcept

Motor uniform scale.

motor & operator*=(int s) noexcept

Motor uniform scale.

motor & operator/=(float s) noexcept

Motor uniform inverse scale.

motor & operator/=(int s) noexcept

Motor uniform inverse scale.

float scalar() const noexcept

float e12() const noexcept

float e21() const noexcept

float e31() const noexcept

float e13() const noexcept

float e23() const noexcept

float e32() const noexcept

float e01() const noexcept

float e10() const noexcept

float e02() const noexcept

float e20() const noexcept

float e03() const noexcept

float e30() const noexcept

float e0123() const noexcept

motor KLN_VEC_CALL operator+(motor a,motor b) noexcept

Motor addition.

motor KLN_VEC_CALL operator-(motor a,motor b) noexcept

Motor subtraction.

motor KLN_VEC_CALL operator*(motor l,float s) noexcept

Motor uniform scale.

motor KLN_VEC_CALL operator*(motor l,int s) noexcept

Motor uniform scale.

motor KLN_VEC_CALL operator*(float s,motor l) noexcept

Motor uniform scale.

motor KLN_VEC_CALL operator*(int s,motor l) noexcept

Motor uniform scale.

motor KLN_VEC_CALL operator/(motor r,float s) noexcept

Motor uniform inverse scale.

motor KLN_VEC_CALL operator/(motor r,int s) noexcept

Motor uniform inverse scale.

motor KLN_VEC_CALL operator-(motor m) noexcept

Unary minus.

motor KLN_VEC_CALL operator~(motor m) noexcept

Reversion operator.