Skip to main content

A Tiny Python Package for Quaternions

Project description

tinyQuaternion

A tiny python module for Quaternions

Author: Reza Ahmadzadeh - 2019

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
q1.add(q2)

# 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.]))
>>> 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 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. Tutorials

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:

"initial 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)

"rotated cube"

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)

"rotated cube"

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tinyquaternion-0.0.1.tar.gz (6.1 kB view hashes)

Uploaded Source

Built Distribution

tinyquaternion-0.0.1-py3-none-any.whl (6.7 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page