> For the complete documentation index, see [llms.txt](https://jewels86.gitbook.io/axinite/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jewels86.gitbook.io/axinite/axana/quaternions-and-angles.md).

# 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`.

```python
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:

```python
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:

```python
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:

```python
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]))
```

{% hint style="info" %}
You can use `angle_between_degrees` if you don't want to work with radians.
{% endhint %}

## Other Functions

```python
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)
```
