Simbody  3.6
SimTK::Quaternion_< P > Class Template Reference

A Quaternion is a Vec4 with the following behavior: More... Inheritance diagram for SimTK::Quaternion_< P >:

## Public Member Functions

Quaternion_ ()
Default constructor produces the ZeroRotation quaternion [1 0 0 0] (not NaN - even in debug mode). More...

Quaternion_ (const Quaternion_ &q)
Zero-cost copy constructor just copies the source without conversion to canonical form or normalization. More...

Quaternion_operator= (const Quaternion_ &q)
Zero-cost copy assignment just copies the source without conversion to canonical form or normalization. More...

Quaternion_ (RealP e0, RealP e1, RealP e2, RealP e3)
Construct a quaternion from four scalars and normalize the result, which costs about 40 flops. More...

Quaternion_ (const Vec4P &q)
Construct a quaternion from a 4-vector and normalize the result, which costs about 40 flops. More...

Quaternion_ (const Rotation_< P > &)
Constructs a canonical quaternion from a rotation matrix (cost is about 60 flops). More...

void setQuaternionToZeroRotation ()
The ZeroRotation quaternion is [1 0 0 0]. More...

void setQuaternionToNaN ()
Set quaternion to all-NaN. More...

void setQuaternionFromAngleAxis (const Vec4P &av)
Set this quaternion from an angle-axis rotation packed into a 4-vector as [a vx vy vz]. More...

void setQuaternionFromAngleAxis (const RealP &a, const UnitVec< P, 1 > &v)
Set this quaternion from an angle-axis rotation provided as an angle a and a separate unit vector [vx vy vz]. More...

Vec4P convertQuaternionToAngleAxis () const
Returns [ a vx vy vz ] with (a,v) in canonical form, i.e., -180 < a <= 180 and |v|=1. More...

const Vec4PasVec4 () const
Zero-cost cast of a Quaternion_ to its underlying Vec4; this is not converted to axis-angle form. More...

Quaternion_normalizeThis ()
Normalize an already constructed quaternion in place; but do you really need to do this? Quaternions should be kept normalized at all times. More...

Quaternion_ normalize () const
Return a normalized copy of this quaternion; but do you really need to do this? Quaternions should be kept normalized at all times. More...

Quaternion_ (const Vec4P &v, bool)
Use this constructor only if you are sure v is normalized to 1.0. More... Public Member Functions inherited from SimTK::Vec< 4, P >
ScalarNormSq scalarNormSqr () const
Scalar norm square is sum( conjugate squares of all underlying scalars ), where conjugate square of scalar s is conj(s)*s. More...

TSqrt sqrt () const
Elementwise square root; that is, the return value has the same length as this Vec but with each element replaced by whatever it thinks its square root is. More...

TAbs abs () const
Elementwise absolute value; that is, the return value has the same dimension as this Vec but with each element replaced by whatever it thinks its absolute value is. More...

TStandard standardize () const
Return a copy of this Vec but with the underlying scalar type converted (if necessary) to one of the C++ standard real or complex floating point types. More...

EStandard sum () const
Sum just adds up all the elements into a single return element that is the same type as this Vec's elements except standardized to use one of the C++ built-in real or complex types as its underlying scalars. More...

Vec ()
Default construction initializes Vec's elements to NaN when debugging but leaves them uninitialized garbage otherwise, so declarations have zero cost in Release builds. More...

Vec (const Vec &src)
Copy constructor copies the logically-included elements from the source Vec; gaps due to stride are not accessed in either source or destination. More...

Vec (const Vec< M, E, SS > &src)
This is an implicit conversion from a Vec of the same length and element type but with a different stride. More...

Vec (const Vec< M, ENeg, SS > &src)
This is an implicit conversion from a Vec of the same length and negated element type (possibly with a different stride). More...

Vec (const Vec< M, EE, SS > &src)
Construct a Vec from a Vec of the same length, with any stride. More...

Vec (const E &e)
Construction from a single value of this Vec's element type assigns that value to each element. More...

Vec (const ENeg &ne)
Construction from a single value of this Vec's negated element type assigns that value to each element, requiring floating point negation to be performed once to compute the type-E representation of the type negator<E> value provided. More...

Vec (int i)
Given an int value, turn it into a suitable floating point number, convert that to element type E and then feed that to the above single-element constructor. More...

Vec (const E &e0, const E &e1)
Construct a Vec<2,E> from two elements of type E, etc. More...

Vec (const E &e0, const E &e1, const E &e2)

Vec (const E &e0, const E &e1, const E &e2, const E &e3)

Vec (const E &e0, const E &e1, const E &e2, const E &e3, const E &e4)

Vec (const E &e0, const E &e1, const E &e2, const E &e3, const E &e4, const E &e5)

Vec (const E &e0, const E &e1, const E &e2, const E &e3, const E &e4, const E &e5, const E &e6)

Vec (const E &e0, const E &e1, const E &e2, const E &e3, const E &e4, const E &e5, const E &e6, const E &e7)

Vec (const E &e0, const E &e1, const E &e2, const E &e3, const E &e4, const E &e5, const E &e6, const E &e7, const E &e8)

Vec (const EE *p)
Construction from a pointer to elements of any type EE assumes we're pointing at a C++ array of EE's of the right length, and that EE is assignment compatible with this Vec's element type E. More...

Vecoperator= (const Vec &src)
Copy assignment operator copies the logically-included elements from the source Vec; gaps due to stride are not accessed in either source or destination. More...

Vecoperator= (const EE *p)
Assignment to a pointer to elements of any type EE assumes we're pointing at a C++ array of EE's of the right length, and that EE is assignment compatible with this Vec's element type E. More...

Vecoperator= (const Vec< M, EE, SS > &vv)
Assignment to a conforming Vec, of any element type and stride, provided that the element types are assignment-compatible. More...

Vecoperator= (const EE &e)

Vecoperator+= (const Vec< M, EE, SS > &r)
Add in a conforming Vec, of any element type and stride, provided that the element types are addition-compatible. More...

Vecoperator+= (const Vec< M, negator< EE >, SS > &r)
Add in a conforming Vec, of any negated element type and stride, provided that the element types are addition-compatible. More...

Vecoperator+= (const EE &e)

Vecoperator-= (const Vec< M, EE, SS > &r)
Subtract off a conforming Vec, of any element type and stride, provided that the element types are addition-compatible. More...

Vecoperator-= (const Vec< M, negator< EE >, SS > &r)
Subtract off a conforming Vec, of any negated element type and stride, provided that the element types are addition-compatible. More...

Vecoperator-= (const EE &e)

Vec< M, typename CNT< E >::template Result< EE >::Add > conformingAdd (const Vec< M, EE, SS > &r) const
Vector addition – use operator+ instead. More...

Vec< M, typename CNT< E >::template Result< EE >::Sub > conformingSubtract (const Vec< M, EE, SS > &r) const
Vector subtraction – use operator- instead. More...

Mat< M, M, typename CNT< E >::template Result< EE >::Mul > conformingMultiply (const Row< M, EE, SS > &r) const
Same as outer product (m = col*row) – use operator* or outer() instead. More...

Vec< M, typename CNT< E >::template Result< EE >::Mul > elementwiseMultiply (const Vec< M, EE, SS > &r) const
Elementwise multiply (Matlab " .* " operator). More...

Vec< M, typename CNT< E >::template Result< EE >::Dvd > elementwiseDivide (const Vec< M, EE, SS > &r) const
Elementwise divide (Matlab " ./ " operator). More...

const Eoperator[] (int i) const
Select an element of this Vec and return a const reference to it. More...

Eoperator[] (int i)
Select an element of this Vec and return a writable reference to it. More...

const Eoperator() (int i) const
Same as const operator[] above. More...

Eoperator() (int i)
Same as non-const operator[] above. More...

ScalarNormSq normSqr () const

CNT< ScalarNormSq >::TSqrt norm () const

TNormalize normalize () const
If the elements of this Vec are scalars, the result is what you get by dividing each element by the norm() calculated above. More...

TInvert invert () const
This method is not supported for Vec objects. More...

const Vecoperator+ () const
Unary plus does nothing. More...

const TNegoperator- () const
Unary minus recasts this Vec to a type that has the opposite interpretation of the sign but is otherwise identical, so no computation or copying is performed here. More...

TNegoperator- ()
Recast to negated type and return a writable reference; writing to this will cause the negated result to be placed in the original Vec. More...

const THermoperator~ () const
The Hermitian transpose operator recasts this Vec to a type that specifies the opposite storage order (row vs. column) then returns a reference, so no computation or copying is performed here. More...

THermoperator~ ()
Recast to Hermitian transposed type and return a writable reference; the effect is that writing to elements of the result affects the transposed element of the original Vec. More...

const TNegnegate () const
Non-operator version of unary negation; just a recast. More...

TNegupdNegate ()
Non-operator version of unary negation; recasts and returns a writable reference. More...

const THermtranspose () const
Non-operator version of Hermitian transpose; just a recast. More...

THermupdTranspose ()
Non-operator version of Hermitian transpose; recasts and returns a writable reference. More...

const TPosTranspositionalTranspose () const
Positional transpose turns this Vec into a Row but does not transpose the individual elements. More...

TPosTransupdPositionalTranspose ()
Positional transpose returning a writable reference. More...

const TRealreal () const
Return a reference to the real portion of this Vec if it has complex elements; otherwise the type doesn't change. More...

TRealreal ()
Recast to show only the real portion of this Vec and return a writable reference. More...

const TImagimag () const
Return a reference to the imaginary portion of this Vec if it has complex elements; otherwise the type doesn't change. More...

TImagimag ()
Recast to show only the imaginary portion of this Vec and return a writable reference. More...

const TWithoutNegatorcastAwayNegatorIfAny () const
Recast to remove negators from this Vec's type if present; this is handy for simplifying operations where we know the sign can be ignored such as squaring. More...

TWithoutNegatorupdCastAwayNegatorIfAny ()
Recast to remove negators from this Vec's type if present and return a writable reference. More...

Vec< M, typename CNT< E >::template Result< EE >::Mul > scalarMultiply (const EE &e) const

Vec< M, typename CNT< EE >::template Result< E >::Mul > scalarMultiplyFromLeft (const EE &e) const

Vec< M, typename CNT< E >::template Result< EE >::Dvd > scalarDivide (const EE &e) const

Vec< M, typename CNT< EE >::template Result< E >::Dvd > scalarDivideFromLeft (const EE &e) const

Vec< M, typename CNT< E >::template Result< EE >::Add > scalarAdd (const EE &e) const

Vec< M, typename CNT< E >::template Result< EE >::Sub > scalarSubtract (const EE &e) const

Vec< M, typename CNT< EE >::template Result< E >::Sub > scalarSubtractFromLeft (const EE &e) const

Vecoperator*= (const EE &e)

Vecoperator/= (const EE &e)

VecscalarEq (const EE &ee)

VecscalarEq (int ee)

VecscalarPlusEq (const EE &ee)

VecscalarPlusEq (int ee)

VecscalarMinusEq (const EE &ee)

VecscalarMinusEq (int ee)

VecscalarMinusEqFromLeft (const EE &ee)

VecscalarMinusEqFromLeft (int ee)

VecscalarTimesEq (const EE &ee)

VecscalarTimesEq (int ee)

VecscalarTimesEqFromLeft (const EE &ee)

VecscalarTimesEqFromLeft (int ee)

VecscalarDivideEq (const EE &ee)

VecscalarDivideEq (int ee)

VecscalarDivideEqFromLeft (const EE &ee)

VecscalarDivideEqFromLeft (int ee)

void setToNaN ()
Set every scalar in this Vec to NaN; this is the default initial value in Debug builds, but not in Release. More...

void setToZero ()
Set every scalar in this Vec to zero. More...

const Vec< MM, P, STRIDE > & getSubVec (int i) const
Extract a const reference to a sub-Vec with size known at compile time. More...

Vec< MM, P, STRIDE > & updSubVec (int i)
Extract a writable reference to a sub-Vec with size known at compile time. More...

Vec< M-1, P, 1 > drop1 (int p) const
Return a vector one smaller than this one by dropping the element at the indicated position p. More...

Vec< M+1, P, 1 > append1 (const EE &v) const
Return a vector one larger than this one by adding an element to the end. More...

Vec< M+1, P, 1 > insert1 (int p, const EE &v) const
Return a vector one larger than this one by inserting an element before the indicated one. More...

bool isNaN () const
Return true if any element of this Vec contains a NaN anywhere. More...

bool isInf () const
Return true if any element of this Vec contains a +Infinity or -Infinity somewhere but no element contains a NaN anywhere. More...

bool isFinite () const
Return true if no element of this Vec contains an Infinity or a NaN anywhere. More...

bool isNumericallyEqual (const Vec< M, E2, RS2 > &v, double tol) const
Test whether this vector is numerically equal to some other vector with the same shape, using a specified tolerance. More...

bool isNumericallyEqual (const Vec< M, E2, RS2 > &v) const
Test whether this vector is numerically equal to some other vector with the same shape, using a default tolerance which is the looser of the default tolerances of the two objects being compared. More...

bool isNumericallyEqual (const P &e, double tol=getDefaultTolerance()) const
Test whether every element of this vector is numerically equal to the given element, using either a specified tolerance or the vector's default tolerance (which is always the same or looser than the default tolerance for one of its elements). More...

std::string toString () const
Print Vec into a string and return it. More...

void set (int i, const E &value)
Variant of operator[] that's scripting friendly to set ith entry. More...

const Eget (int i) const
Variant of operator[] that's scripting friendly to get const reference to ith entry. More...

## Additional Inherited Members Public Types inherited from SimTK::Vec< 4, P >
enum
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef P E
Element type of this Vec. More...

typedef CNT< E >::TNeg ENeg
Negated version of this Vec's element type; ENeg==negator< E >. More...

typedef CNT< E >::TWithoutNegator EWithoutNegator
Element type, stripped of negator<> if it has one. More...

typedef CNT< E >::TReal EReal
Type showing just the real part of an element of this Vec if elements are complex; otherwise just the element type. More...

typedef CNT< E >::TImag EImag
Type showing the imaginary part of an element of this Vec as real, if elements are complex; otherwise a type that can hold a zero of the element type. More...

typedef CNT< E >::TComplex EComplex
Type that elements would have if complex, if E is currently real; otherwise just the element type E. More...

typedef CNT< E >::THerm EHerm
Type of the Hermitian transpose of an element of this Vec. More...

typedef CNT< E >::TPosTrans EPosTrans
Type of a positional transpose of an element of this Vec. More...

typedef CNT< E >::TSqHermT ESqHermT
Type of the expression ~E*E (default vector and matrix square; symmetric). More...

typedef CNT< E >::TSqTHerm ESqTHerm
Type of the expression E*~E ("row square"; symmetric). More...

typedef CNT< E >::TSqrt ESqrt
Type required to hold the result of sqrt(E). More...

typedef CNT< E >::TAbs EAbs
Type required to hold the result of abs(E). More...

typedef CNT< E >::TStandard EStandard
Return type of standardize(E) method; a packed type that can hold the value of an element after eliminating negator and conjugate types. More...

typedef CNT< E >::TInvert EInvert
Packed type that can hold the value returned from invert(E), the inverse type of an element. More...

typedef CNT< E >::TNormalize ENormalize
Packed type that can hold the value returned from normalize(E). More...

typedef CNT< E >::Scalar EScalar
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef CNT< E >::ULessScalar EULessScalar
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef CNT< E >::Number ENumber
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef CNT< E >::StdNumber EStdNumber
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef CNT< E >::Precision EPrecision
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef CNT< E >::ScalarNormSq EScalarNormSq
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef Vec< M, E, STRIDE > T
The type of this Vec. More...

typedef Vec< M, ENeg, STRIDE > TNeg
Type this Vec would have if its elements were interpreted as negated. More...

typedef Vec< M, EWithoutNegator, STRIDE > TWithoutNegator
Type of this Vec with negator removed from its element type, if the element is negated. More...

typedef Vec< M, EReal, STRIDE *CNT< E >::RealStrideFactorTReal
Type of this Vec cast to show only the real part of its element; this might affect the stride. More...

typedef Vec< M, EImag, STRIDE *CNT< E >::RealStrideFactorTImag
Type of this Vec cast to show only the imaginary part of its element; this might affect the stride. More...

typedef Vec< M, EComplex, STRIDE > TComplex
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef Row< M, EHerm, STRIDE > THerm
Type of this Vec after casting to its Hermitian transpose; that is, the Vec turns into a Row and each element turns into its Hermitian transpose. More...

typedef Row< M, E, STRIDE > TPosTrans
Type of this Vec after casting to its positional transpose; that is, the Vec turns into a Row but the element type remains unchanged. More...

typedef E TElement
Element type of this Vec. More...

typedef E TRow
Type of a row of this CNT object (for a Vec, just its element type). More...

typedef Vec TCol
Type of a column of this CNT object (for a Vec, the whole thing). More...

typedef Vec< M, ESqrt, 1 > TSqrt
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef Vec< M, EAbs, 1 > TAbs
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef Vec< M, EStandard, 1 > TStandard
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef Row< M, EInvert, 1 > TInvert
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef Vec< M, ENormalize, 1 > TNormalize
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef ESqHermT TSqHermT
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef SymMat< M, ESqTHermTSqTHerm
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef EScalar Scalar
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef EULessScalar ULessScalar
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef ENumber Number
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef EStdNumber StdNumber
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef EPrecision Precision
These compile-time constants are required of every Composite Numerical Type (CNT). More...

typedef EScalarNormSq ScalarNormSq
These compile-time constants are required of every Composite Numerical Type (CNT). More... Static Public Member Functions inherited from SimTK::Vec< 4, P >
static int size ()
The number of elements in this Vec (note that stride does not affect this number.) More...

static int nrow ()
The number of rows in a Vec is the number of elements. More...

static int ncol ()
The number of columns in a Vec is always 1. More...

static const VecgetSubVec (const Vec< MM, P, STRIDE > &v, int i)
Extract a subvector of type Vec from a longer one that has the same element type and stride, and return a const reference to the selected subsequence. More...

static VecupdSubVec (Vec< MM, P, STRIDE > &v, int i)
Extract a subvector of type Vec from a longer one that has the same element type and stride, and return a writable reference to the selected subsequence. More...

static const VecgetAs (const P *p)
Recast an ordinary C++ array E[] to a const Vec<M,E,S>; assumes compatible length, stride, and packing. More...

static VecupdAs (P *p)
Recast a writable ordinary C++ array E[] to a writable Vec<M,E,S>; assumes compatible length, stride, and packing. More...

static Vec< M, P, 1 > getNaN ()
Return a Vec of the same length and element type as this one but with all elements set to NaN. More...

static double getDefaultTolerance ()
For approximate comparisons, the default tolerance to use for a vector is the same as its elements' default tolerance. More...

## Detailed Description

### template<class P> class SimTK::Quaternion_< P >

A Quaternion is a Vec4 with the following behavior:

• its length is always 1 (or else it is all NaN)
• it is equivalent to an angle/axis rotation for angle a, axis unit vector v, as: q = [ cos(a/2) sin(a/2)*v ] A quaternion is in "canonical form" when its first element is nonnegative. This corresponds to rotation angles in the range -180 < a <= 180 degrees. Quaternions are not required to be in canonical form (e.g., during numerical integration). When appropriate, they are put in canonical form.

Conversion from quaternion to (angle,axis) form is handled here also. (angle,axis) is in canonical form when -180 < angle <= 180 and |axis|=1. However, (angle,axis) is meaningful for any angle and for any axis where |axis| > 0.

## ◆ Quaternion_() [1/6]

template<class P >
 SimTK::Quaternion_< P >::Quaternion_ ( )
inline

Default constructor produces the ZeroRotation quaternion [1 0 0 0] (not NaN - even in debug mode).

## ◆ Quaternion_() [2/6]

template<class P >
 SimTK::Quaternion_< P >::Quaternion_ ( const Quaternion_< P > & q )
inline

Zero-cost copy constructor just copies the source without conversion to canonical form or normalization.

## ◆ Quaternion_() [3/6]

template<class P >
 SimTK::Quaternion_< P >::Quaternion_ ( RealP e0, RealP e1, RealP e2, RealP e3 )
inline

Construct a quaternion from four scalars and normalize the result, which costs about 40 flops.

## ◆ Quaternion_() [4/6]

template<class P >
 SimTK::Quaternion_< P >::Quaternion_ ( const Vec4P & q )
inlineexplicit

Construct a quaternion from a 4-vector and normalize the result, which costs about 40 flops.

## ◆ Quaternion_() [5/6]

template<class P >
 SimTK::Quaternion_< P >::Quaternion_ ( const Rotation_< P > & )
explicit

Constructs a canonical quaternion from a rotation matrix (cost is about 60 flops).

## ◆ Quaternion_() [6/6]

template<class P >
 SimTK::Quaternion_< P >::Quaternion_ ( const Vec4P & v, bool )
inline

Use this constructor only if you are sure v is normalized to 1.0.

This zero cost method is faster than the Quaternion(Vec4) constructor which normalizes the Vec4. The second argument forces the compiler to call the fast constructor; it is otherwise ignored. By convention, set the second argument to "true".

## ◆ operator=()

template<class P >
 Quaternion_& SimTK::Quaternion_< P >::operator= ( const Quaternion_< P > & q )
inline

Zero-cost copy assignment just copies the source without conversion to canonical form or normalization.

## ◆ setQuaternionToZeroRotation()

template<class P >
 void SimTK::Quaternion_< P >::setQuaternionToZeroRotation ( )
inline

The ZeroRotation quaternion is [1 0 0 0].

Note: Default constructor is ZeroRotation (unlike Vec4P which start as NaN in Debug mode).

## ◆ setQuaternionToNaN()

template<class P >
 void SimTK::Quaternion_< P >::setQuaternionToNaN ( )
inline

Set quaternion to all-NaN.

Note that this is not the same as produced by default construction, even in Debug mode – default construction always produces an identity rotation of [1 0 0 0].

## ◆ setQuaternionFromAngleAxis() [1/2]

template<class P >
 void SimTK::Quaternion_< P >::setQuaternionFromAngleAxis ( const Vec4P & av )

Set this quaternion from an angle-axis rotation packed into a 4-vector as [a vx vy vz].

The result will be put in canonical form, i.e., it will have a non-negative first element. If the "axis" portion of av is a zero vector on input, the quaternion is set to all-NaN.

## ◆ setQuaternionFromAngleAxis() [2/2]

template<class P >
 void SimTK::Quaternion_< P >::setQuaternionFromAngleAxis ( const RealP & a, const UnitVec< P, 1 > & v )

Set this quaternion from an angle-axis rotation provided as an angle a and a separate unit vector [vx vy vz].

The result will be put in canonical form, i.e., it will have a non-negative first element.

## ◆ convertQuaternionToAngleAxis()

template<class P >
 Vec4P SimTK::Quaternion_< P >::convertQuaternionToAngleAxis ( ) const

Returns [ a vx vy vz ] with (a,v) in canonical form, i.e., -180 < a <= 180 and |v|=1.

## ◆ asVec4()

template<class P >
 const Vec4P& SimTK::Quaternion_< P >::asVec4 ( ) const
inline

Zero-cost cast of a Quaternion_ to its underlying Vec4; this is not converted to axis-angle form.

## ◆ normalizeThis()

template<class P >
 Quaternion_& SimTK::Quaternion_< P >::normalizeThis ( )
inline

Normalize an already constructed quaternion in place; but do you really need to do this? Quaternions should be kept normalized at all times.

One of the advantages of using them is that you don't have to check if they are normalized or renormalize them. However, under some situations they do need renormalization, but it is costly if you don't actually need it. If the quaternion is exactly zero, set it to [1 0 0 0]. If its magnitude is 0 < magnitude < epsilon (epsilon is machine tolerance), set it to NaN (treated as an error). Otherwise, normalize the quaternion which costs about 40 flops. The quaternion is NOT put in canonical form.

## ◆ normalize()

template<class P >
 Quaternion_ SimTK::Quaternion_< P >::normalize ( ) const
inline

Return a normalized copy of this quaternion; but do you really need to do this? Quaternions should be kept normalized at all times.

One of the advantages of using them is that you don't have to check if they are normalized or renormalize them. However, under some situations they do need renormalization, but it is costly if you don't actually need it.