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(pos : Indexable(Vec3), to ref_pos : Indexable(Vec3), weights : Indexable(Float64)) : self

Returns the transformation that aligns pos onto ref_pos minimizing the weighted RMSD, where weights sets the relative weight of each coordinate pair. Raises ArgumentError if the sets differ in size.

Source

Class methods

aligning_ensemble(frames : Indexable(AtomView), width : Float64 = 1.0, tolerance : Float64 = 1e-4, max_iterations : Int32 = 100) : Array(self)

Returns the transformations that align each of frames (atoms paired by index) onto their mean, iteratively down-weighting mobile atoms with Gaussian weights exp(-rmsf² / (2 * width²)) so the fit rests on the rigid core. Iterates until no weight changes by more than tolerance; raises ConvergenceError after max_iterations.

The aligned frames do not depend on the input orientation of each frame or on frame order; the common frame is that of frames[0].

Source