struct

Chem::Spatial::Transform

Inherits Struct / Value / Object

A Transform encodes an affine transformation in 3D space such as translation, scaling, rotation, reflection, and more.

An affine transformation is the composition of a linear map A (3x3 matrix) and a translation b (3x1 vector), which can be represented by the augmented 4x4 matrix:

[ A   b ]
[ 0   1 ]

where the bottom row is [0, 0, 0, 1]. This representation encodes the linear map and translation in a single matrix, which allows to combine and apply transformations by matrix multiplication. Additionally, the affine transformation matrix has some properties that allows for efficient code (see the multiplication operator with a vector). For further details, refer to the Wikipedia article.

The transformation is internally represented by a Mat3 (#linear_map) and Vec3 (#offset) instances.

Examples

scaling = Transform.scaling(2)
translation = Transform.translation(Vec3[1, 2, 3])
vec = Vec3[1, 0, 1]

# apply the transformation
scaling * vec     # => Vec3[2.0, 0.0, 2.0]
translation * vec # => Vec3[2.0, 2.0, 4.0]
# or
vec.transform(scaling)     # => Vec3[2.0, 0.0, 2.0]
vec.transform(translation) # => Vec3[2.0, 2.0, 4.0]

# note that multiplication is not commutative
scaling * vec # => Vec3[2.0, 0.0, 2.0]
vec * scaling # => Vec3[0.5, 0.0, 0.5] # inverse transformation

# combine transformations
translate_scale = scaling * translation # translates then scales
translate_scale * vec                   # => Vec3[4.0, 4.0, 8.0]
scale_translate = translation * scaling # scales than translates
scale_translate * vec                   # => Vec3[3.0, 2.0, 5.0]

# chain methods for composing a transformation
transform = Transform.scaling(2).translate(Vec3[1, 2, 3])
transform * vec # => Vec3[3.0, 2.0, 5.0]

Constructors

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

Returns a transformation 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
aligning(u : Vec3, to v : Vec3) : self

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

Source
aligning(pos : CoordinatesProxy, to ref_pos : CoordinatesProxy) : self

Returns the transformation encoding the rotation and traslation to align pos onto ref_pos. Raises ArgumentError if the two coordinate sets are of different size.

The optimal rotation matrix is computed by minimizing the root mean square deviation (RMSD) using the QCP method (refer to Spatial.qcp for details).

Source
aligning(pos : AtomCollection, to ref_pos : AtomCollection) : self
Source
identity

Returns the identity transformation.

Source
new(linear_map : Mat3, offset : Vec3 = Vec3.zero)

Creates a new transformation with linear_map and offset.

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

Returns a transformation that rotates by the Euler angles in degrees. Delegates to Quat.rotation for computing the rotation.

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

Returns a transformation that rotates about the axis vector rotaxis by angle degrees. Delegates to Quat.rotation for computing the rotation.

Source
rotation(quat : Quat) : self

Returns a transformation that applies the rotation encoded by the given quaternion.

Source
scaling(sx : Number, sy : Number, sz : Number) : self

Returns a transformation that scales by the given factors.

Source
scaling(factor : Number) : self

Returns a transformation that scales by factor.

Source
translation(offset : Vec3) : self

Returns a transformation that translates by offset.

Source

Instance methods

*(rhs : self) : self

Returns the multiplication of the transformation by rhs. It effectively combines two transformation.

NOTE: Multiplication of transformations is not commutative, i.e., a * b != b * a.

scaling = Transform.scaling(2)
translation = Transform.translation(Vec3[1, 2, 3])
vec = Vec3[1, 0, 1]

translate_scale = scaling * translation # translates then scales
translate_scale * vec                   # => Vec3[4.0, 4.0, 8.0]
scale_translate = translation * scaling # scales than translates
scale_translate * vec                   # => Vec3[3.0, 2.0, 5.0]
Source
*(rhs : Vec3) : Vec3

Returns the multiplication of the transformation by rhs. It effectively applies the transformation to rhs.

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

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

Source
inv

Returns the inverse transformation.

The algorithm exploits the fact that the affine transformation matrix is defined as

[ A   b ]
[ 0   1 ]

where A is the linear map (3x3 matrix), b is the translation vector (3x1 vector), and the bottom row is [0, 0, 0, 1]. In such case, the inverse matrix can be computed as

[ inv(A)   -inv(A) * b ]
[   0            1     ]

where inv(A) is computed following the standard procedure (see Inversion of 3x3 matrices at Wikipedia).

Refer to the Affine Transformation Wikipedia article for a detailed explanation or this answer in Stack Overflow.

Source
linear_map

Linear map encoded as a 3x3 matrix.

Source
offset

Translation vector.

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

Returns the transformation rotated by the given Euler angles in degrees. Delegates to Quat.rotation for computing the rotation.

Source
rotate(about rotaxis : Vec3, by angle : Number) : self

Returns the transformation rotated about rotaxis by angle degrees. Delegates to Quat.rotation for computing the rotation.

Source
rotate(quat : Quat) : self

Returns the transformation rotated by the given quaternion.

Source
rotation

Returns the rotation component of the transformation.

Source
scale(sx : Number, sy : Number, sz : Number) : self

Returns the transformation scaled by the given factors.

Source
scale(by factor : Number) : self

Returns the transformation scaled by factor.

Source
to_s(io : IO) : Nil

Same as #inspect(io).

Source
transform(by transform : self) : self

Returns the transformation transformed by transform. It effectively combines two transformations.

Source
translate(by offset : Vec3) : self

Returns the transformation translated by the given offset.

Source
translation

Returns the translation component of the transformation.

Source