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 zaxis
// 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 yzdirection. 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 columnmajor matrix representing this motor's action as a linear transformation. The motor must be normalized for this conversion to produce welldefined results, but is more efficient than a 4x4 matrix conversion. 
public mat4x4 as_mat4x4 () const noexcept 
Convert this motor to a 4x4 columnmajor 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 columnmajor matrix representing this motor's action as a linear transformation. The motor must be normalized for this conversion to produce welldefined results, but is more efficient than a 4x4 matrix conversion.
mat4x4 as_mat4x4() const noexcept
Convert this motor to a 4x4 columnmajor 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.