A Tiny Python Package for Quaternions

# tinyQuaternion

A tiny python module for Quaternions

## 1. Installation

Clone the repository. For separate projects you need to copy the tinyQuaternion.py file into your source folder and import the module as follows:

from tinyQuaternion import Quaternion


The only dependency is numpy, so import it as follows:

import numpy as np


## 2. Documentation

### 2.1 Define Quaternions

In this package, there are two methods to define a quaternion:

1. using a 4D array representing the elements of a quaternion q=[w,x,y,z]. Define the array using numpy's ndarray.
q = Quaternion(q=np.array([0., 0., 1., 0.]))

>>> q
Quaternion(0.0, 0.0, 1.0, 0.0)

1. using an axis-angle representation. Use n for denoting the axis of rotation and a for denoting the angle of rotation in radians.
q = Quaternion(a=np.pi/3, n=np.array([0.,0.,1.]))

q
Quaternion(0.8660254037844387, 0.0, 0.0, 0.49999999999999994)


### 2.2. Quaternion elements

Each quaternion is a vector q=[w,x,y,z] with four elements w, x, y, z. Each element of the quaternion can be retrieved as follows:

q.w
q.x
q.y
q.z


Example:

>>> q.w
0.8660254037844387
>>> q.x
0.0
>>> q.y
0.0
>>> q.z
0.49999999999999994
>>>


### 2.3. Scalar and Vector parts

To retrieve the scalar part of the quaternion, w use the scalar method as follows:

q.scalar


and to retrieve the vector part of the quaternion, [x,y,z] use the vector method as follows:

q.vector


Example:

>>> q.scalar
0.8660254037844387
>>> q.vector
array([0. , 0. , 0.5])
>>>


### 2.4. Magnitude

Get the norm or magnitude of the quaternion as follows:

q.magnitude


Example

>>> q.magnitude
1.0


### 2.5. Check if the quaternion is normalized

To see if the quaternion is normalized you can use the is_unit() method. This will return True if the magnitude of the quaternion is equal to 1 and False otherwise.

q.is_unit()


Example:

>>> q.is_unit()
True


### 2.6. Normalize

To normalize the quaternion use the normalized method.

q.normalized


Example:

>>> q.normalized
Quaternion(0.8660254037844387, 0.0, 0.0, 0.49999999999999994)


### 2.7. Conjugate

To retrieve the conjugate of a quaternion q=[w,x,y,z] as q*=[w,-x,-y,-z] use the conjugate method as follows:

q.conjugate


Example:

>>> q.conjugate
Quaternion(0.8660254037844387, -0.0, -0.0, -0.49999999999999994)


### 2.8. Inverse

To retrieve the inverse of a quaternion use the inverse method as follows:

q.inverse


Example:

>>> q.inverse
Quaternion(0.8660254037844387, -0.0, -0.0, -0.49999999999999994)


### 2.9. Extract Axis-Angle from Quaternion

To 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

# addition

# subtraction
q1.sub(q2)

# multiplication
q1.mul(q2)

# division
q1.div(q2)


Example:

>>> q1 = Quaternion(np.array([1.,0.,0.,0.]))
>>> q2 = Quaternion(np.array([0.,0.,0.,1.]))
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 Log

To get logarithm of a quaternion perform

q.log


Example:

>>> q=Quaternion(np.array([0.,1.,0.,0.]))
>>> q
Quaternion(0.0, 1.0, 0.0, 0.0)
>>> q.log
Quaternion(0.0, 1.5707963267948966, 0.0, 0.0)


### 2.12. Quaternion Exp

To get exponential of a quaternion perform

q.exp


Example:

>>> q=Quaternion(np.array([0.,1.,0.,0.]))
>>> q
Quaternion(0.0, 1.0, 0.0, 0.0)
>>> q.exp
Quaternion(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.1. Rotation Using Quaternions

The code can be found in the test folder. First import all the required packages:

import numpy as np
from tinyQuaternion import Quaternion
from plotCube import plot_cube


To perform this test, we first plot a cube using the function plotCube.py provided in the test folder.

# plot the initial cube
p1 = 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 quaternion
q = Quaternion(a=np.pi/2, n=np.array([0., 1., 0.]))


By using the a and n keywords, 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 method rotatePoint as follows:

# rotate the cube
p1r = q.rotatePoint(p1)
p2r = q.rotatePoint(p2)
p3r = q.rotatePoint(p3)
p4r = q.rotatePoint(p4)


and plot the rotated cube

cube2 = [
(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 90


Now, we should combine the two quaternions. The rule is that "First rotation should go last", so we can write

q = 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)


## Project details

Uploaded source
Uploaded py3