Package: tinyquaternion
tinyQuaternionA tiny python module for QuaternionsAuthor: Reza Ahmadzadeh - 20191. InstallationClone the repository. For separate projects you need to copy thetinyQuaternion.pyfile into your source folder and import the module as follows:fromtinyQuaternionimportQuaternionThe only dependency isnumpy, so import it as follows:importnumpyasnp2. Documentation2.1 Define QuaternionsIn this package, there are two methods to define a quaternion:using a 4D array representing the elements of a quaternionq=[w,x,y,z]. Define the array using numpy'sndarray.q=Quaternion(q=np.array([0.,0.,1.,0.]))>>>qQuaternion(0.0,0.0,1.0,0.0)using an axis-angle representation. Usenfor denoting the axis of rotation andafor denoting the angle of rotation in radians.q=Quaternion(a=np.pi/3,n=np.array([0.,0.,1.]))qQuaternion(0.8660254037844387,0.0,0.0,0.49999999999999994)2.2. Quaternion elementsEach quaternion is a vectorq=[w,x,y,z]with four elementsw,x,y,z. Each element of the quaternion can be retrieved as follows:q.wq.xq.yq.zExample:>>>q.w0.8660254037844387>>>q.x0.0>>>q.y0.0>>>q.z0.49999999999999994>>>2.3. Scalar and Vector partsTo retrieve the scalar part of the quaternion,wuse thescalarmethod as follows:q.scalarand to retrieve the vector part of the quaternion,[x,y,z]use thevectormethod as follows:q.vectorExample:>>>q.scalar0.8660254037844387>>>q.vectorarray([0.,0.,0.5])>>>2.4. MagnitudeGet the norm or magnitude of the quaternion as follows:q.magnitudeExample>>>q.magnitude1.02.5. Check if the quaternion is normalizedTo see if the quaternion is normalized you can use theis_unit()method. This will returnTrueif the magnitude of the quaternion is equal to 1 andFalseotherwise.q.is_unit()Example:>>>q.is_unit()True2.6. NormalizeTo normalize the quaternion use thenormalizedmethod.q.normalizedExample:>>>q.normalizedQuaternion(0.8660254037844387,0.0,0.0,0.49999999999999994)2.7. ConjugateTo retrieve the conjugate of a quaternionq=[w,x,y,z]asq*=[w,-x,-y,-z]use theconjugatemethod as follows:q.conjugateExample:>>>q.conjugateQuaternion(0.8660254037844387,-0.0,-0.0,-0.49999999999999994)2.8. InverseTo retrieve the inverse of a quaternion use theinversemethod as follows:q.inverseExample:>>>q.inverseQuaternion(0.8660254037844387,-0.0,-0.0,-0.49999999999999994)2.9. Extract Axis-Angle from QuaternionTo extract the axis-angle form of a quaternion use this method as follows:q.axisangle()Example:>>>q.axisangle()(array([0.,0.,1.]),1.0471975511965974)keep in mind that this is not equal to the original quaternion that we defined above. The main reason is that we have performed some operations on the original quaternion.2.10. Main operations# additionq1.add(q2)# subtractionq1.sub(q2)# multiplicationq1.mul(q2)# divisionq1.div(q2)Example:>>>q1=Quaternion(np.array([1.,0.,0.,0.]))>>>q2=Quaternion(np.array([0.,0.,0.,1.]))>>>q1.add(q2)Quaternion(1.0,0.0,0.0,1.0)>>>q1.sub(q2)Quaternion(1.0,0.0,0.0,-1.0)>>>q1.mul(q2)Quaternion(0.0,0.0,0.0,1.0)>>>q1.div(q2)Quaternion(0.0,0.0,0.0,-1.0)Note that these operations do not perfrom normalization implicitly.2.11. Quaternion LogTo get logarithm of a quaternion performq.logExample:>>>q=Quaternion(np.array([0.,1.,0.,0.]))>>>qQuaternion(0.0,1.0,0.0,0.0)>>>q.logQuaternion(0.0,1.5707963267948966,0.0,0.0)2.12. Quaternion ExpTo get exponential of a quaternion performq.expExample:>>>q=Quaternion(np.array([0.,1.,0.,0.]))>>>qQuaternion(0.0,1.0,0.0,0.0)>>>q.expQuaternion(0.5403023058681398,0.8414709848078965,0.0,0.0)2.13. Rotate point in 3D space using Quaternion (axis-angle)q.rotatePoint(p)Example:The point should be define using a 3D numpy array as follows:>>>q=Quaternion(a=np.pi/3,n=np.array([0.,0.,1.]))>>>p=np.array([1.,2.,-1.])>>>q.rotatePoint(p)array([-1.23205081,1.8660254,-1.])3. Tutorials3.1. Rotation Using QuaternionsThe code can be found in thetestfolder. First import all the required packages:importnumpyasnpfromtinyQuaternionimportQuaternionfromplotCubeimportplot_cubeTo perform this test, we first plot a cube using the functionplotCube.pyprovided in the test folder.# plot the initial cubep1=np.array([0.,0.,0.])p2=np.array([0.,.1,0.])p3=np.array([2.,0.,0.])p4=np.array([0.,0.,.1])cube1=[(p1[0],p1[1],p1[2]),(p2[0],p2[1],p2[2]),(p3[0],p3[1],p3[2]),(p4[0],p4[1],p4[2])]plot_cube(cube1)This will result in the following cube:Now, we define a known quaternion. Assume, we want to rotate about Y-axis by 90 degrees. The quaternion will look like this:# define a known quaternionq=Quaternion(a=np.pi/2,n=np.array([0.,1.,0.]))By using theaandnkeywords, we tell the function that we are representing the quaternion by defining the angle and axis of rotation.Now, we rotate each point using the quaternion through the methodrotatePointas follows:# rotate the cubep1r=q.rotatePoint(p1)p2r=q.rotatePoint(p2)p3r=q.rotatePoint(p3)p4r=q.rotatePoint(p4)and plot the rotated cubecube2=[(p1r[0],p1r[1],p1r[2]),(p2r[0],p2r[1],p2r[2]),(p3r[0],p3r[1],p3r[2]),(p4r[0],p4r[1],p4r[2])]plot_cube(cube2)Now let's perform two rotations using quaternions. We consider a new rotation and then combine it with the previous rotation.
Our previous rotation was about Y-axis by 90 degrees. For this one we want to have a rotation about X-axis by 90 degrees. The quaternion will look like this:q2=Quaternion(a=np.pi/2,n=np.array([1.,0.,0.]))# rotate about x by 90Now, we should combine the two quaternions. The rule is that "First rotation should go last", so we can writeq=q2.mul(q)This quaternion has the effect of a rotation about Y-axis, followed by a rotation about X-axis.Now perform the rotation:p1r=q.rotatePoint(p1)p2r=q.rotatePoint(p2)p3r=q.rotatePoint(p3)p4r=q.rotatePoint(p4)and plot the rotated cube:cube3=[(p1r[0],p1r[1],p1r[2]),(p2r[0],p2r[1],p2r[2]),(p3r[0],p3r[1],p3r[2]),(p4r[0],p4r[1],p4r[2])]plot_cube(cube3)