struct

Chem::Spatial::Quat

Inherits Struct / Value / Object

The quaternion is a mathematical construct that extends the complex numbers and it is useful to encode three-dimensional rotations. Quats are represented by four numbers (w, x, y, z), where w is considered as the real (scalar) part and x, y, z the imaginary (vector) part. Rotations can be encoded as a unit quaternion using the axis-angle representation, where x, y, z correspond to the rotation axis and w to the rotation angle by the following formula:

q(v, t) = q(w, x, y, z) = q(cos(t/2), sin(t/2)vx, sin(t/2)vy, sin(t/2)vz)

where v is a unit vector and t is the rotation angle. Quats have several useful mathematical properties, e.g., quaternion multiplication can be used to represent a sequence of rotations producing a single quaternion. Indeed, the rotation encoded in the quaternion q can be applied to a ordinary vector p simply by

p* = q * p * q-1

where q-1 is the inverse of q and p* is the rotated vector (see Quat#* for details).

Examples

q = Quat[1, 2, 3, 4]
q                 # => [1.0 2.0 3.0 4.0]
q.real            # => 1.0
q.imag            # => [2.0 3.0 4.0]
q.w               # => 1.0
q.x               # => 2.0
q.y               # => 3.0
q.z               # => 4.0
-q                # => [-1.0 -2.0 -3.0 -4.0]
q.abs             # => 5.477225575051661
q.abs2            # => 30.0
q.conj            # => [1.0 -2.0 -3.0 -4.0]
q.inv             # => [0.033 -0.067 -0.1 -0.133]
q.normalize       # => [0.183 0.365 0.548 0.730]
q.unit?           # => false
q.normalize.unit? # => true
q.zero?           # => false

q * 2  # => [2.0 4.0 6.0 8.0]
q / 10 # => [0.2 0.4 0.6 0.8]

p = Quat[4, 3, 2, 1]
p + q # => [5.0 5.0 5.0 5.0]
p * q # => [-12.0 16.0 4.0 22.0]
q * p # => [-12.0 6.0 24.0 12.0]

Use the convenience methods to encode rotations.

v = Vec3[1, 2, 3]
q = Quat.aligning v, to: Vec3[1, 0, 0]
q * v # => [3.742 0.0 0.0]
# or
v.transform(q)    # => [3.742 0.0 0.0]
(q * v).normalize # => [1.0 0.0 0.0]

q = Quat.rotation Vec3[0, 1, 0], by: 90
q * v # => [3.0 2.0 -1.0]
v * q # => [-3.0 2.0 1.0]

NOTE: Quat multiplication is not commutative: q * v != v * p, the former will apply the rotation encoded in q to v but the latter will produce the inverse rotation. Use Vec3#transform to avoid the ambiguity.

Constructors

[](w : Float64, x : Float64, y : Float64, z : Float64) : self

Returns a quaternion with w as the real (scalar) part and x, y, and z as the vector (imaginary) part.

Source
aligning(u : Vec3, to v : Vec3) : self

Returns a quaternion encoding the rotation operation to align u to v.

Source
aligning(u : Tuple(Vec3, Vec3), to v : Tuple(Vec3, Vec3)) : self

Returns a quaternion encoding the rotation to align u[0] to v[0] and u[1] to v[1].

First compute the alignment of u[0] to v[0], then the alignment of the transformed u[1] to v[1] on the plane perpendicular to v[0] by taking their projections.

Source
identity

Returns the identity quaternion (no rotation).

Source
new(w : Float64, x : Float64, y : Float64, z : Float64)

Creates a new quaternion with w as the real (scalar) part and x, y, and z as the vector (imaginary) part.

Source
rotation(x : Number, y : Number, z : Number) : self

Returns a quaternion encoding the rotation by the Euler angles.

The rotation rotates x degrees around the X axis, y degrees around the Y axis, and z degrees around the y axis; applied in that order (XYZ).

Source
rotation(about rotaxis : Vec3, by theta : Number) : self

Returns a quaternion encoding the rotation about the axis vector rotaxis by theta degrees.

Source

Instance methods

*(rhs : self) : self

Returns the Hamilton product of the quaternion and rhs.

Source
*(rhs : Vec3) : Vec3

Returns the conjugate of rhs by the quaternion.

The conjugate of rhs is calculated as p* = q * p * q^-1, where p is a quaternion whose vector part is rhs and real part equals zero. Thus, the resulting quaternion is computed using the Hamilton product and its vector part corresponds to p*. Such operation can be written as (self * rhs.to_q * inv).imag, but this method implements an optimized version by using some vector and quaternion identities. The faster method is taken from this post of the molecular matters blog.

If the quaternion encodes a rotation about an axis, this effectively applies such rotation to rhs.

Source
*(rhs : Number) : self

Returns the element-wise multiplication of the quaternion by rhs.

Source
+(rhs : self) : self

Returns the element-wise addition of the quaternion by rhs.

Source
-(rhs : self) : self

Returns the element-wise subtraction of the quaternion by rhs.

Source
-

Returns the negation of the quaternion.

Source
/(rhs : Number) : self

Returns the element-wise division of the quaternion by rhs.

Source
abs

Returns the absolute value (norm) using the Pythagorean theorem.

Source
abs2

Returns the square of the absolute value (norm).

Source
close_to?(rhs : self, delta : Number = Float64::EPSILON) : Bool

Returns true if the elements of the quaternions are within delta from each other, else false.

Quat[1, 2, 3, 4].close_to?(Quat[1, 2, 3, 4])                     # => true
Quat[1, 2, 3, 4].close_to?(Quat[1.001, 1.999, 3.00004, 4], 1e-3) # => true
Quat[1, 2, 3, 4].close_to?(Quat[4, 3, 2, 1])                     # => false
Quat[1, 2, 3, 4].close_to?(Quat[1.001, 1.999, 3.00004, 4], 1e-8) # => false
Source
conj

Returns the conjugate of the quaternion.

Source
dot(rhs : self) : Float64

Returns the dot product of the quaternion and rhs.

Source
imag

Returns the imaginary part of the quaternion.

Source
inv

Returns the inverse of the quaternion.

Source
normalize

Returns the normalized quaternion of the quaternion.

Source
real

Returns the real part of the quaternion.

Source
to_mat3

Returns the rotation matrix equivalent to the quaternion.

Source
to_s(io : IO) : Nil

Same as #inspect(io).

Source
unit?

Returns true if the quaternion is a unit quaternion, else false.

Source
w

Real (scalar) part of the quaternion.

Source
x

X component of the imaginary (vector) part of the quaternion.

Source
y

Y component of the imaginary (vector) part of the quaternion.

Source
z

Z component of the imaginary (vector) part of the quaternion.

Source
zero?

Returns true if the quaternion is a zero quaternion, else false.

Source