geometry

Overview

rowan.geometry.distance Determine the distance between quaternions p and q.
rowan.geometry.sym_distance Determine the distance between quaternions p and q.
rowan.geometry.riemann_exp_map Compute the exponential map on the Riemannian manifold \(\mathbb{H}^*\).
rowan.geometry.riemann_log_map Compute the log map on the Riemannian manifold \(\mathbb{H}^*\).
rowan.geometry.intrinsic_distance Compute the intrinsic distance between quaternions.
rowan.geometry.sym_intrinsic_distance Compute the symmetrized intrinsic distance between quaternions.
rowan.geometry.angle Compute the angle of rotation of a quaternion.

Details

Various tools for working with the geometric representation of quaternions.

A particular focus is computing the distance between quaternions. These distance computations can be complicated, particularly good metrics for distance on the Riemannian manifold representing quaternions do not necessarily coincide with good metrics for similarities between rotations. An overview of distance measurements can be found in this paper.

rowan.geometry.distance(p, q)

Determine the distance between quaternions p and q.

This is the most basic distance that can be defined on the space of quaternions; it is the metric induced by the norm on this vector space \(\rho(p, q) = \lvert\lvert p - q \rvert\rvert\).

When applied to unit quaternions, this function produces values in the range \([0, 2]\).

Parameters:
Returns:

Distances between p and q.

Return type:

(…) numpy.ndarray

Example:

>>> rowan.geometry.distance([1, 0, 0, 0], [1, 0, 0, 0])
0.0
rowan.geometry.sym_distance(p, q)

Determine the distance between quaternions p and q.

This is a symmetrized version of distance() that accounts for the fact that \(p\) and \(-p\) represent identical rotations. This makes it a useful measure of rotation similarity.

Parameters:

When applied to unit quaternions, this function produces values in the range \([0, \sqrt{2}]\).

Returns:Symmetrized distances between p and q.
Return type:(…) numpy.ndarray

Example:

>>> rowan.geometry.sym_distance([1, 0, 0, 0], [-1, 0, 0, 0])
0.0
rowan.geometry.riemann_exp_map(p, v)

Compute the exponential map on the Riemannian manifold \(\mathbb{H}^*\).

The nonzero quaternions form a Lie algebra \(\mathbb{H}^*\) that is also a Riemannian manifold. In general, given a point \(p\) on a Riemannian manifold \(\mathcal{M}\) and an element of the tangent space at \(p\), \(v \in T_p\mathcal{M}\), the Riemannian exponential map is defined by the geodesic starting at \(p\) and tracing out an arc of length \(v\) in the direction of \(v\). This function computes the endpoint of that path (which is itself a quaternion).

Explicitly, we define the exponential map as

\[\begin{equation} \textrm{Exp}_p(v) = p\exp(v) \end{equation}\]
Parameters:
  • p ((…, 4) numpy.ndarray) – Points on the manifold of quaternions.
  • v ((…, 4) numpy.ndarray) – Tangent vectors to traverse.
Returns:

The endpoints of the geodesic starting from \(p\) and traveling a distance \(\lvert\lvert v\rvert\rvert\) in the direction of \(v\).

Return type:

(…, 4) numpy.ndarray

Example:

rowan.geometry.riemann_exp_map([1, 0, 0, 0], [-1, 0, 0, 0])
rowan.geometry.riemann_log_map(p, q)

Compute the log map on the Riemannian manifold \(\mathbb{H}^*\).

This function inverts riemann_exp_map(). See that function for more details. In brief, given two quaternions p and q, this method returns a third quaternion parameterizing the geodesic passing from p to q. It is therefore an important measure of the distance between the two input quaternions.

Parameters:
Returns:

The quaternions pointing from \(p\) to \(q\) with magnitudes equal to the length of the geodesics joining these quaternions.

Return type:

(…, 4) numpy.ndarray

Example:

>>> rowan.geometry.riemann_log_map([1, 0, 0, 0], [-1, 0, 0, 0])
array([0., 0., 0., 0.])
rowan.geometry.intrinsic_distance(p, q)

Compute the intrinsic distance between quaternions.

The quaternion distance is determined as the length of the quaternion joining the two quaternions (see riemann_log_map()). Rather than computing this directly, however, as shown in [Huynh09] we can compute this distance using the following equivalence:

\[\begin{equation} \lvert\lvert \log(p q^{-1}) \rvert\rvert = 2\cos(\lvert\langle p, q \rangle\rvert) \end{equation}\]

When applied to unit quaternions, this function produces values in the range \([0, \pi]\).

[Huynh09]Huynh DQ (2009) Metrics for 3D rotations: comparison and analysis. J Math Imaging Vis 35(2):155-164
Parameters:
Returns:

Intrinsic distances between p and q.

Return type:

(…) numpy.ndarray

Example:

rowan.geometry.intrinsic_distance([1, 0, 0, 0], [-1, 0, 0, 0])
rowan.geometry.sym_intrinsic_distance(p, q)

Compute the symmetrized intrinsic distance between quaternions.

This is a symmetrized version of intrinsic_distance() that accounts for the double cover \(SU(2)\rightarrow SO(3)\), making it a more useful metric for rotation similarity.

When applied to unit quaternions, this function produces values in the range \([0, \frac{\pi}{2}]\).

Parameters:
Returns:

Symmetrized intrinsic distances between p and q.

Return type:

(…) numpy.ndarray

Example:

>>> rowan.geometry.sym_intrinsic_distance([1, 0, 0, 0], [-1, 0, 0, 0])
array(0.)
rowan.geometry.angle(p)

Compute the angle of rotation of a quaternion.

Note that this is identical to 2*intrinsic_distance(p, np.array([1, 0, 0, 0])).

Parameters:p ((…, 4) numpy.ndarray) – Array of quaternions.
Returns:Angles traced out by the rotations p.
Return type:(…) numpy.ndarray

Example:

>>> rowan.geometry.angle([1, 0, 0, 0])
0.0