1 unstable release
0.2.0 | Feb 18, 2023 |
---|
#812 in Math
53KB
1K
SLoC
qrotate
The qrotate
crate provides Quaternion representations of rotations of 3-element vectors representing points in 3-dimensional space. 3-element vectors can use rust standard library types, or vectors from the ndarray
crate.
Copyright (c) 2023 Steven Michael (ssmichael@gmail.com)
Overview
Quaternion rotations are represented as multiply (*
) operations, and possible on the following repersentations of 3D vectors, where T
is a template parameter matching a floating-point type, f32
or f64
.
[T; 3] |
3-element fixed-size array |
&[T; 3] |
Reference to 3-element fixed size array |
&[T] |
Slice containing 3 elements |
std::vec::Vec<T> |
standard library vector with 3 elements |
&std::vec::Vec<T> |
Reference to standard library vector with 3 elements |
ndarray::Array1<'a, T> |
1D array from ndarray crate (with ndarray feature enabled) |
ndarray::ArrayView1<'a, T> |
View into 1D array from ndarray crate (with ndarray feature enabled) |
Quaternions can also be multiplied with other quaternions via the *
operator to represent a concatenation of rotations.
The above operations are also defined to work when used by a reference to a quaternion.
Note: this quaternion represetntation uses the "conventional" definition of a quaternion, which when constructed from an axis and and angle, defines a right-handed rotation of a vector about the given axis by the given angle.
Examples
Simple Rotation
Rotation of the x-axis unit vector about the z axis by π/2
use std::f64::consts::PI;
let xhat = [1.0, 0.0, 0.0];
let yhat = qrotate::Quaternion::<f64>>rotz(PI / 2.0) * xhat
// yhat = [0.0, 1.0, 0.0];
Concatenated Rotations
Rotation of the x-axis unit vector about z axis by π/2 then y axis by π/3
use std::f64::consts::PI;
let xhat = [1.0, 0.0, 0.0];
let q1 = qrotate::Quaternion::<f64>::rotz(PI / 2.0);
let q2 = qrotate::Quaternion::<f64>::roty(PI / 3.0);
let result q2 * q1 * xhat
Find quaternion to rotate between two vectors
Find quaterion that rotates from xhat vector to yhat vector
let xhat = [1.0, 0.0, 0.0];
let yhat = [0.0, 1.0, 0.0];
let q = qrotation::qv1tov2(&xhat, &yhat);
Direction-Cosine Matrix
Represent quaternion as a direction-cosine matrix (DCM) that left-multiplies a vector to perform a rotation or a direction-cosine matrix that right-multiples a 2D (Nx3) column matrix to perform a rotation
use std::f64::consts::PI;
let q = qrotate::Quaternion::<f64>::rotz(PI / 2.0);
// get [[f64; 3]; 3] representation of quaternion as DCM
// that left-multiples row vector
let dcm = q.ldcm();
// Same thing, excpet DCM as ndarray::Array2<f64>
let dcm_ndarr = q.ldcm_ndarr();
// Same thing, except DCM as ndarray::Array2<f64>
// that right-multiplies column vector
let dcm_ndarr = q.rdcm_ndarr();
Convert Direction-Cosine Matrix (DCM) to quaternion
use std::f64::consts::PI;
let q = qrotate::Quaternion::<f64>::rotz(PI / 2.0);
// get [[f64; 3]; 3] representation of quaternion as DCM
// that left-multiples row vector
let dcm = q.ldcm();
// Convert back to quaternion
let q2 = Quaternion::<f64>::from_ldcm(dcm);
Axis, Angle
Convert quaternion to and from axis and angle of rotation representations
// Construct quaternion representing rotation about zhat axis by PI/2
let zhat = [0.0, 1.0, 0.0]
let theta = std::f64::consts::PI / 2.0;
let q = Quaternion::<f64>::from_axis_angle(zhat, theta);
// Result is same as zhat
let axis: [f64; 3] = q.axis();
// result is PI / 2.0
let angle: f64 = q.angle();
Other Operations
Miscelaneous operations below
// Construct identity quaternion (no rotation)
let mut q = Quaternion::<f64>::identity();
// now rotate about y axis
q = Quaternion::<f64>::qroty(0.1) * q;
// Get conjugate
let qc = q.conjugate();
// Get quaternion norm (should be 1.0 most of the time)
let n = q.norm();
// Scale quaternion
q = q * 2.0;
// Get normalized version of quaternion
let qn = q.normalized();
// Normalize quaternion in place
q.normalize();
// Get vector elements of quaternion
let v: [f64; 3] = q.vector();
// Get scalar elements of quaternion
let w: f64 = q.scalar();
Python Bindings
By enabling the python
feature, the crate also has the option to compile into a python library. The library makes available a "Quaternion" class which can be used to rotate 3-element NumPy vectors (and each element of a Nx3 NumPy "matrix"). Many of the functions described above are available in python
Dependencies
~1.3–7.5MB
~45K SLoC