Quaternion Manual
maxon::Quaternion is a MAXON API class used to represent quaternions and deliver standard mathematical operations. Unit quaternions, also known as versors, provide a convenient mathematical notation for representing orientations and rotations of objects in three dimensions. Compared to Euler angles they are simpler to compose and avoid the problem of gimbal lock. Compared to rotation matrices they are more compact, more numerically stable, and may be more efficient.
// This example shows how to use a quaternion to rotate a point in a left-handed coordinate system.// define the point to rotate const maxon::Vector point (1, 0, 0); DiagnosticOutput (diagIDString + "start point: @" , point);
// define the rotation angle const maxon::Float rotAngle(90);
// define the rotation axis const maxon::Vector rotAxis(0, 0, 1);
// create a quaternion representing the point const maxon::Quaternion<maxon::Float> quaternionPointA(point, 0); DiagnosticOutput (diagIDString + "quaternionPointA: @" , quaternionPointA);
// create the quaternion represention the rotation (q) const maxon::Float a = rotAxis.x * sin( maxon::DegToRad (rotAngle/2)); const maxon::Float b = rotAxis.y * sin( maxon::DegToRad (rotAngle/2)); const maxon::Float c = rotAxis.z * sin( maxon::DegToRad (rotAngle/2)); const maxon::Float d = cos( maxon::DegToRad (rotAngle/2)); const maxon::Quaternion<maxon::Float> quaternion(a, b, c, d); DiagnosticOutput (diagIDString + "quaternion: @" , quaternion);
// get the conjugated quaternion (q') const maxon::Quaternion<maxon::Float> quaternionCnj = quaternion. GetConjugate (); DiagnosticOutput (diagIDString + "quaternionCnj: @" , quaternionCnj);
// get the rotated point p1 = q * p * q' const maxon::Quaternion<maxon::Float> quanterionPointARot = quaternion * quaternionPointA * quaternionCnj; DiagnosticOutput (diagIDString + "quanterionPointARot: @" , quanterionPointARot);
// extract the rotation point const maxon::Vector rotPoint = quanterionPointARot. v ; DiagnosticOutput (diagIDString + "rotated point: @" , rotPoint);
A maxon::Quaternion instance can be created on the stack and initialized through the proper method using a numerical data type as template:
// just allocate an zero-valued quaternion object const maxon::Quaternion<maxon::Float> zeroQuaternion;
// just allocate a quaternion object defining the vectorial part and the real part const maxon::Vector vectorVal(1.0, 1.0, 0); const maxon::Float floatVal(1.5); const maxon::Quaternion<maxon::Float> vectorRealQuaternion(vectorVal, floatVal);
// just allocate a quaternion object defining the four components used to value vectorial and real part const maxon::Float a = 0.2; // 1st vectorial component const maxon::Float b = 0.4; // 2nd vectorial component const maxon::Float c = 0.6; // 3rd vectorial component const maxon::Float d = 0.8; // this the real part const maxon::Quaternion<maxon::Float> fourComponentsQuaternion(a, b, c, d);
The maxon::Quaternion class delivers a set of standard mathematical operators to perform calculation with quaternion. The operators deliver are:
// just allocate a constant quaternion using the four components const maxon::Quaternion<maxon::Float> quaternionA(1, 0, 0, 12); DiagnosticOutput (diagIDString + "quaternionA: @" , quaternionA);
// just allocate a quaternion equal to the previous one maxon::Quaternion<maxon::Float> quaternionB = quaternionA; DiagnosticOutput (diagIDString + "quaternionB: @" , quaternionB);
// sum A to B quaternionB += quaternionA; DiagnosticOutput (diagIDString + "quaternionB += quaternionA: @" , quaternionB);
// subtract A to B quaternionB -= quaternionA; DiagnosticOutput (diagIDString + "quaternionB -= quaternionA: @" , quaternionB);
// sum A and B const maxon::Quaternion<maxon::Float> quaternionAsumB = quaternionA + quaternionB; DiagnosticOutput (diagIDString + "quaternionAsumB : @" , quaternionAsumB);
// subtract A and B const maxon::Quaternion<maxon::Float> quaternionAdifB = quaternionA - quaternionB; DiagnosticOutput (diagIDString + "quaternionAdifB: @" , quaternionAdifB);
// multiply A and B const maxon::Quaternion<maxon::Float> quaternionAprdB = quaternionA * quaternionB; DiagnosticOutput (diagIDString + "quaternionAprdB: @" , quaternionAprdB);
// multiply B and A const maxon::Quaternion<maxon::Float> quaternionBprdA = quaternionB * quaternionA; DiagnosticOutput (diagIDString + "quaternionBprdA: @" , quaternionBprdA);
// scale A by scalar s const maxon::Float scalar = 2; const maxon::Quaternion<maxon::Float> quaternionAscaled = quaternionA * scalar; DiagnosticOutput (diagIDString + "quaternionAscaled: @" , quaternionAscaled);
The maxon::Quaternion class is provided with a number of get methods to retrieve useful data from a maxon::Quaternion instance:
// just allocate a constant quaternion using the four components // representing a rotation of 90 deg around Y-axis in left-handed c.sys const maxon::Quaternion<maxon::Float> quatY90 (0, sin( PI05 /2), 0, cos( PI05 /2));
// get the rotation matrix associated with the quaternion const maxon::Matrix rotMat = quatY90.GetMatrix();
// get the axis and rotation angle associated with the quaternion maxon::Vector rotAxis; maxon::Float rotAngle; quatY90.GetAxisRotation(rotAxis, rotAngle) iferr_return ;
// get the squared length of the quaternion const maxon::Float valSqLength = quatY90.GetSquaredLength();
// get the length of the quaternion const maxon::Float valLength = quatY90.GetLength();
// get the normalized quaternion const maxon::Quaternion<maxon::Float> quatNormalized = quatY90. GetNormalized () iferr_return ;
// get the inverse quaternion const maxon::Quaternion<maxon::Float> quatInverted = quatY90. GetInverse () iferr_return ;
// get the conjugate quaternion const maxon::Quaternion<maxon::Float> quatConjugated = quatY90. GetConjugate ();
// get the natural log quaternion const maxon::Quaternion<maxon::Float> quatLog = quatY90. GetLog () iferr_return ;
// get the exponential equaternion const maxon::Quaternion<maxon::Float> quatExp = quatY90. GetExp () iferr_return ;
// get the quaternion elevated to the given power const maxon::Quaternion<maxon::Float> quatPow = quatY90. GetPow (3.0) iferr_return ;
// get the dot product of two quaternion const maxon::Float valDotProduct = maxon::Quaternion<maxon::Float>::GetDot (quatY90, quatConjugated);
// get the linear interpolation of the given quaternion and the given blend ratio const maxon::Quaternion<maxon::Float> quatX90 (sin( PI05 /2), 0, 0, cos( PI05 /2)); const maxon::Quaternion<maxon::Float> quatLERP = maxon::Quaternion<maxon::Float>::GetLerp (quatY90, quatX90, 0.5) iferr_return ;
// get the spherical linear interpolation of the given quaternion and the given blend ratio const maxon :: Quaternion < maxon :: Float > quatSLERP = maxon :: Quaternion < maxon :: Float >::GetSlerp(quatY90, quatX90, 0.5) iferr_return ;
// get the spherical quadrangle interpolation of a sequence of quaternions qi and qi+1 using the passed blend parameter const maxon :: Quaternion < maxon :: Float > quatA (1, 0, 0, 1); const maxon :: Quaternion < maxon :: Float > quatAp1 (1, 1, 0, 1); const maxon :: Quaternion < maxon :: Float > quatB (0, 0, 1, 1); const maxon :: Quaternion < maxon :: Float > quatBp1 (0, 1, 1, 1); const maxon :: Quaternion < maxon :: Float > quatSQUAD = maxon :: Quaternion < maxon :: Float >::GetSquad(quatA, quatAp1, quatB, quatBp1, 0.4) iferr_return ;
// get the inner quaternion from a sequance of quaternions qi-1, qi and qi+1 const maxon :: Quaternion < maxon :: Float > quatCm1 (-1, 1, 0, 1); const maxon :: Quaternion < maxon :: Float > quatC (1, 1, 0, 1); const maxon :: Quaternion < maxon :: Float > quatCp1 (2, 1, 0, 1); const maxon :: Quaternion < maxon :: Float > quatInner = maxon :: Quaternion < maxon :: Float >::GetInnerQuaternion(quatCm1, quatC, quatCp1) iferr_return ;
// get the spline quaternion from a sequence of quaternions const maxon :: Quaternion < maxon :: Float > quatDm1 (0, 0, 0, 1); const maxon :: Quaternion < maxon :: Float > quatD (1, 0, 0, 1); const maxon :: Quaternion < maxon :: Float > quatDp1 (2, 0, 0, 2); const maxon :: Quaternion < maxon :: Float > quatDp2 (3, 0, 0, 2); const maxon :: Quaternion < maxon :: Float > quatSpline = maxon :: Quaternion < maxon :: Float >::GetSpline(quatDm1, quatD, quatDp1, quatDp2, 0.75) iferr_return ;
The maxon::Quaternion class is provided with a number of "set" methods to define a maxon::Quaternion instance:
// allocate a constant transformation matrix representing // a rotation of 90 deg around Y-axis in left-handed c.sys const maxon::SqrMat3<maxon::Vector> mat3x3( maxon::Vector (0, 0, 1), maxon::Vector (0, 1, 0), maxon::Vector (-1.0, 0.0, 0.0));
// allocate a quaternion and set the values accordingly to the matrix defined maxon::Quaternion<maxon::Float> quatA; quatA. SetMatrix (mat3x3);
// allocate a Eulerian rotation vector (each component of the vector // represents a rotation around an axis) represeting a rotation of 90 deg // around Y-axis in left-handed c.sys const maxon::Vector rotVet (0.0, PI05 , 0.0);
// allocate a quaternion and set the values accordingly to the vector defined maxon::Quaternion<maxon::Float> quatB; quatB. SetRotation (rotVet);
// allocate a vector representing a rotation axis and value representing the rotation amount const maxon::Vector rotAxis (0.0, 1.0, 0.0); const maxon::Float rotAngle( PI05 );
// allocate a quaternion and set the values accordingly to the axis and angle defined maxon::Quaternion<maxon::Float> quatC; quatC. SetAxisRotation (rotAxis, rotAngle);
The maxon::Quaternion class can be used to easily perform a rotation on a geometrical entity.
// allocate a point on X-axis const maxon::Vector point_on_X (1.0, 0.0, 0.0);// define the rotation around the Y-axis const maxon::Vector axis_Y (0.0, 1.0, 0.0);
// define the rotation amount in radians const maxon::Float rot_angle ( PI05 );
// allocate and define the quaternion used to rotate the point maxon::Quaternion<maxon::Float> rotate_on_Y; rotate_on_Y. SetAxisRotation (axis_Y, rot_angle);
// the new point should now be on the Z-axis const maxon::Vector point_on_Z = rotate_on_Y. GetMatrix () * point_on_X;
A maxon::Quaternion instance can be converted to maxon::String using:
// just allocate a complex object const maxon::Quaternion<maxon::Float> quatA(1, 1, 0, 1); const maxon::String stringQuaternion = quatA. ToString ( nullptr ); DiagnosticOutput (diagIDString + "quatA: @" , quatA); DiagnosticOutput (diagIDString + "quatA.ToString(): @" , stringQuaternion);
A maxon::Quaternion instance can be read from and written to disk by serializing the data contained using the conventional functions.
// This example shows how to store and retrieve a maxon::Quaternion from a file. const maxon::Quaternion<maxon::Float> savedQuat(1, 1, 0, 1);// file URL const maxon::Url url = (targetFolder + "quaternion.txt" _s) iferr_return ; const maxon::Id fileID( "net.maxonexample.quaternion" );
// save to file maxon::WriteDocument (url, maxon::OPENSTREAMFLAGS::NONE , fileID, savedQuat, maxon::IOFORMAT::JSON ) iferr_return ;
// read from file maxon::Quaternion<maxon::Float> loadedQuat; maxon::ReadDocument (url, fileID, loadedQuat) iferr_return ;