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.