Quaternions and Angles

A guide to handling quaternions and angles in axana.

In this guide, you'll:

  • Represent rotations using quaternions

  • Apply quaternions to vectors

  • Calculate both the angle and quaternion between to vectors

Quaternions

Imagine we're writing an autopilot for a rocket in a simulation. In our modifier, we'll need to correct the direction our rocket is heading in. We can calculate the quaternion difference between the current direction and the target direction with axana.

import axinite as ax
import axinite.analysis as axana

# ... code ...
target = ax.unit_vector_jit(target_position - body["r"][n])
quaternion = axana.quaternion_between(target, body["v"[n])

We can then shift our velocity along the quaternion:

target = axana.apply_quaternion(target, quaternion)

Angles

Let's say Bob is trying to explain the orbital state of the Moon around the Earth in a simulation with spherical coordinates (3D polar coordinates). Since Axinite uses the Cartesian coordinate system, Bob will need to calculate the polar and azimuthal angles.

First, Bob will place the origin at (0, 0, 0). Then, Bob will choose that timestep he wants to describe:

import axinite as ax
import axinite.analysis as axana
import numpy as np

TIMESTEP = 0

# ... code ...
state = ax.state(body, TIMESTEP)

Then, he'll calculate the components of the coordinate with:

r = ax.vector_magnitude_jit(state[0]) # Distance component
theta = axana.angle_between(np.array([state[0], state[1], 0), np.array([1, 0, 0]))
phi = axana.angle_between(np.array([0, state[1], state[2]), np.array([0, 0, 1]))

You can use angle_between_degrees if you don't want to work with radians.

Other Functions

import axinite as ax
import axinite.analysis as axana
import numpy as np


v1 = np.array([1, 0, 1])
v2 = np.array([0, 1, 0])

quaternion = axana.quaternion_between(v1, v2)
quaternion_conjugate = axana.quaternion_conjugate(quaternion)
clipped_quaternion = axana.clip_quaternion_degrees(5)
multiplied_quaternion = axana.quaternion_multiply(quaternion, clipped_quaternion)
applied_v1 = axana.apply_quaternion(v1, quaternion)

angle_between_rad = axana.angle_between(v1, v2)
angle_between_deg = axana.angle_between_degrees(v1, v2)

Last updated