struct Chem::Spatial::Transform
- Chem::Spatial::Transform
- Struct
- Value
- Object
Overview
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]
Defined in:
chem/spatial/transform.cr:53chem/spatial/transform.cr:275
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].
-
.aligning(u : Vec3, to v : Vec3) : self
Returns a transformation encoding the rotation operation to align u to v.
-
.aligning(pos : CoordinatesProxy, to ref_pos : CoordinatesProxy) : self
Returns the transformation encoding the rotation and traslation to align pos onto ref_pos.
- .aligning(pos : AtomCollection, to ref_pos : AtomCollection) : self
-
.identity : self
Returns the identity transformation.
-
.new(linear_map : Mat3, offset : Vec3 = Vec3.zero)
Creates a new transformation with linear_map and offset.
-
.rotation(x : Number, y : Number, z : Number) : self
Returns a transformation that rotates by the Euler angles in degrees.
-
.rotation(about rotaxis : Vec3, by angle : Number) : self
Returns a transformation that rotates about the axis vector rotaxis by angle degrees.
-
.rotation(quat : Quat) : self
Returns a transformation that applies the rotation encoded by the given quaternion.
-
.scaling(sx : Number, sy : Number, sz : Number) : self
Returns a transformation that scales by the given factors.
-
.scaling(factor : Number) : self
Returns a transformation that scales by factor.
-
.translation(offset : Vec3) : self
Returns a transformation that translates by offset.
Instance Method Summary
-
#*(rhs : self) : self
Returns the multiplication of the transformation by rhs.
-
#*(rhs : Vec3) : Vec3
Returns the multiplication of the transformation by rhs.
- #==(rhs : self) : Bool
-
#close_to?(rhs : self, delta : Float64 = Float64::EPSILON) : Bool
Returns
true
if the elements of the quaternions are within delta from each other, elsefalse
. -
#inv : self
Returns the inverse transformation.
-
#linear_map : Mat3
Linear map encoded as a 3x3 matrix.
-
#offset : Vec3
Translation vector.
-
#rotate(x : Number, y : Number, z : Number) : self
Returns the transformation rotated by the given Euler angles in degrees.
-
#rotate(about rotaxis : Vec3, by angle : Number) : self
Returns the transformation rotated about rotaxis by angle degrees.
-
#rotate(quat : Quat) : self
Returns the transformation rotated by the given quaternion.
-
#rotation : self
Returns the rotation component of the transformation.
-
#scale(sx : Number, sy : Number, sz : Number) : self
Returns the transformation scaled by the given factors.
-
#scale(by factor : Number) : self
Returns the transformation scaled by factor.
-
#to_s(io : IO) : Nil
Same as
#inspect(io)
. -
#transform(by transform : self) : self
Returns the transformation transformed by transform.
-
#translate(by offset : Vec3) : self
Returns the transformation translated by the given offset.
-
#translation : self
Returns the translation component of the transformation.
Constructor Detail
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.
Returns a transformation encoding the rotation operation to align u to v.
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).
Creates a new transformation with linear_map and offset.
Returns a transformation that rotates by the Euler angles in
degrees. Delegates to Quat.rotation
for computing the rotation.
Returns a transformation that rotates about the axis vector
rotaxis by angle degrees. Delegates to Quat.rotation
for
computing the rotation.
Returns a transformation that applies the rotation encoded by the given quaternion.
Returns a transformation that scales by the given factors.
Returns a transformation that scales by factor.
Returns a transformation that translates by offset.
Instance Method Detail
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]
Returns the multiplication of the transformation by rhs. It effectively applies the transformation to rhs.
Returns true
if the elements of the quaternions are within
delta from each other, else false
.
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.
Returns the transformation rotated by the given Euler angles in
degrees. Delegates to Quat.rotation
for computing the rotation.
Returns the transformation rotated about rotaxis by angle
degrees. Delegates to Quat.rotation
for computing the rotation.
Returns the transformation rotated by the given quaternion.
Returns the transformation scaled by the given factors.
Returns the transformation transformed by transform. It effectively combines two transformations.
Returns the transformation translated by the given offset.