Transformations using homogeneous coordinates
More...
|
pure subroutine | mod_cg_transformation::cg_transformation_initialize (transformation, dimension) |
| Initialize the transformation to the identity.
|
|
pure subroutine | mod_cg_transformation::cg_transformation_compose (transformation, target) |
| Compose two transformations.
|
|
pure subroutine | mod_cg_transformation::cg_transformation_add_rotation_x (transformation, angle) |
| Add a rotation around the x axis.
|
|
pure subroutine | mod_cg_transformation::cg_transformation_add_rotation_y (transformation, angle) |
| Add a rotation around the y axis.
|
|
pure subroutine | mod_cg_transformation::cg_transformation_add_rotation_z (transformation, angle) |
| Add a rotation around the z axis.
|
|
pure subroutine | mod_cg_transformation::cg_transformation_add_rotation (transformation, axis, angle) |
| Add a rotation around a given axis.
|
|
pure subroutine | mod_cg_transformation::cg_transformation_add_rotation_cos_sin (transformation, axis, c, s) |
| Add a rotation around a given axis.
|
|
pure subroutine | mod_cg_transformation::cg_transformation_add_translation (transformation, vector) |
| Add a translation.
|
|
pure subroutine | mod_cg_transformation::cg_transformation_add_scale_x (transformation, factor) |
| Add a scaling factor in direction x.
|
|
pure subroutine | mod_cg_transformation::cg_transformation_add_scale_y (transformation, factor) |
| Add a scaling factor in direction y.
|
|
pure subroutine | mod_cg_transformation::cg_transformation_add_scale_z (transformation, factor) |
| Add a scaling factor in direction z.
|
|
pure subroutine | mod_cg_transformation::cg_transformation_add_scale (transformation, vector) |
| Add a scaling in every direction.
|
|
pure double precision function, dimension(size(point)) | mod_cg_transformation::cg_transform_point (transformation, point) |
| Apply a transformation to a point.
|
|
elemental subroutine | mod_cg_transformation::cg_transform_point_elemental (transformation, x0, y0, z0, x, y, z) |
| Apply a transformation to a point.
|
|
pure double precision function, dimension(size(direction)) | mod_cg_transformation::cg_transform_direction (transformation, direction) |
| Apply a transformation to a direction.
|
|
elemental subroutine | mod_cg_transformation::cg_transform_direction_elemental (transformation, x0, y0, z0, x, y, z) |
| Apply a transformation to a direction.
|
|
pure double precision function, dimension(size(point)) | mod_cg_transformation::cg_inverse_transform_point (transformation, point) |
| Apply an inverse transformation to a point.
|
|
elemental subroutine | mod_cg_transformation::cg_inverse_transform_point_elemental (transformation, x0, y0, z0, x, y, z) |
| Apply an inverse transformation to a point.
|
|
pure double precision function, dimension(size(direction)) | mod_cg_transformation::cg_inverse_transform_direction (transformation, direction) |
| Apply an inverse transformation to a direction.
|
|
elemental subroutine | mod_cg_transformation::cg_inverse_transform_direction_elemental (transformation, x0, y0, z0, x, y, z) |
| Apply an inverse transformation to a direction.
|
|
This module contains routines to apply transformations on points and directions in 2D and 3D. Available transformations are scaling, rotation, and translation.
Mathematical formulation
This implementation is based on the homogeneous coordinate system of Möbius. Points and directions, or vectors, are represented by column-matrices composed of 3 rows in 2D and 4 rows in 3D; transformations are represented by 3×3 matrices in 2D and 4×4 matrices in 3D. Their structures are:
!! Rotation Translation
!! ┌───────┴───────┐ ┌─┴─┐
!! ┌─────┬─────┬─────┬─────┐ ┌────┐ ┌────┐
!! │ Sxx │ Rxy │ Rxz │ Tx │ │ Px │ │ Dx │
!! ├─────┼─────┼─────┼─────┤ ├────┤ ├────┤
!! │ Ryx │ Syy │ Ryz │ Ty │ │ Py │ │ Dy │
!! ├─────┼─────┼─────┼─────┤ Points: ├────┤ Directions: ├────┤
!! │ Rzx │ Rzy │ Szz │ Tz │ │ Pz │ │ Dz │
!! ├─────┼─────┼─────┼─────┤ ├────┤ ├────┤
!! │ 0 │ 0 │ 0 │ 1 │ │ 1 │ │ 0 │
!! └─────┴─────┴─────┴─────┘ └────┘ └────┘
!!
where R
coefficients are linked to rotations, T
coefficients are linked to translations, and S
coefficients are linked to rotation and scaling. Points and directions are differentiated by their extra coefficient: 1 for a point and 0 for a direction.
Transformations are applied to points and directions through classical matrix product. Composition of transformations is also applied through matrix product. The reciprocal transformation is obtained by matrix inversion.
How to use transformations?
First, use the module mod_cg_transformation:
use mod_cg_transformation
Then, declare a transformation:
type(t_cg_transformation) :: transformation
Before any use of a transformation, you need to initialize a transformation. To do so, you need to provide the spatial dimension to the initialization routine:
call initialize(transformation, 3)
This operation initializes the transformation matrices to the identity. After that, you can add transformations. For instance, you can add a rotation of pi/4 around the z axis:
You can compose this transformation with a translation with the following code:
Now consider two variables representing a point and a direction, namely:
double precision, dimension(3) :: point, transformed_point
double precision, dimension(3) :: direction, transformed_direction
To apply a transformation on these objects, simply use:
You can apply the inverse transformation to the result:
◆ cg_inverse_transform_direction()
pure double precision function, dimension(size(direction)) mod_cg_transformation::cg_inverse_transform_direction |
( |
class(t_cg_transformation), intent(in) | transformation, |
|
|
double precision, dimension(:), intent(in) | direction ) |
Return the transformed direction.
- Parameters
-
[in] | transformation | transformation |
[in] | direction | direction to transform |
◆ cg_inverse_transform_direction_elemental()
elemental subroutine mod_cg_transformation::cg_inverse_transform_direction_elemental |
( |
type(t_cg_transformation), intent(in) | transformation, |
|
|
double precision, intent(in) | x0, |
|
|
double precision, intent(in) | y0, |
|
|
double precision, intent(in) | z0, |
|
|
double precision, intent(out) | x, |
|
|
double precision, intent(out) | y, |
|
|
double precision, intent(out) | z ) |
Elemental version of cg_inverse_transform_direction. Only in 3D.
- Parameters
-
[in] | transformation | transformation |
[in] | x0,y0,z0 | coordinates of the original point |
[out] | x,y,z | coordinates of the transformed point |
◆ cg_inverse_transform_point()
pure double precision function, dimension(size(point)) mod_cg_transformation::cg_inverse_transform_point |
( |
class(t_cg_transformation), intent(in) | transformation, |
|
|
double precision, dimension(:), intent(in) | point ) |
Return the transformed point.
- Parameters
-
[in] | transformation | transformation |
[in] | point | point to transform |
◆ cg_inverse_transform_point_elemental()
elemental subroutine mod_cg_transformation::cg_inverse_transform_point_elemental |
( |
type(t_cg_transformation), intent(in) | transformation, |
|
|
double precision, intent(in) | x0, |
|
|
double precision, intent(in) | y0, |
|
|
double precision, intent(in) | z0, |
|
|
double precision, intent(out) | x, |
|
|
double precision, intent(out) | y, |
|
|
double precision, intent(out) | z ) |
Elemental version of cg_inverse_transform_point. Only in 3D.
- Parameters
-
[in] | transformation | transformation |
[in] | x0,y0,z0 | coordinates of the original point |
[out] | x,y,z | coordinates of the transformed point |
◆ cg_transform_direction()
pure double precision function, dimension(size(direction)) mod_cg_transformation::cg_transform_direction |
( |
class(t_cg_transformation), intent(in) | transformation, |
|
|
double precision, dimension(:), intent(in) | direction ) |
Return the transformed direction.
- Parameters
-
[in] | transformation | transformation |
[in] | direction | direction to transform |
◆ cg_transform_direction_elemental()
elemental subroutine mod_cg_transformation::cg_transform_direction_elemental |
( |
type(t_cg_transformation), intent(in) | transformation, |
|
|
double precision, intent(in) | x0, |
|
|
double precision, intent(in) | y0, |
|
|
double precision, intent(in) | z0, |
|
|
double precision, intent(out) | x, |
|
|
double precision, intent(out) | y, |
|
|
double precision, intent(out) | z ) |
Elemental version of cg_transform_direction. Only in 3D.
- Parameters
-
[in] | transformation | transformation |
[in] | x0,y0,z0 | coordinates of the original point |
[out] | x,y,z | coordinates of the transformed point |
◆ cg_transform_point()
pure double precision function, dimension(size(point)) mod_cg_transformation::cg_transform_point |
( |
class(t_cg_transformation), intent(in) | transformation, |
|
|
double precision, dimension(:), intent(in) | point ) |
Return the transformed point.
- Parameters
-
[in] | transformation | transformation |
[in] | point | point to transform |
◆ cg_transform_point_elemental()
elemental subroutine mod_cg_transformation::cg_transform_point_elemental |
( |
type(t_cg_transformation), intent(in) | transformation, |
|
|
double precision, intent(in) | x0, |
|
|
double precision, intent(in) | y0, |
|
|
double precision, intent(in) | z0, |
|
|
double precision, intent(out) | x, |
|
|
double precision, intent(out) | y, |
|
|
double precision, intent(out) | z ) |
Elemental version of cg_transform_point. Only in 3D.
- Parameters
-
[in] | transformation | transformation |
[in] | x0,y0,z0 | coordinates of the original point |
[out] | x,y,z | coordinates of the transformed point |
◆ cg_transformation_add_rotation()
pure subroutine mod_cg_transformation::cg_transformation_add_rotation |
( |
class(t_cg_transformation), intent(inout) | transformation, |
|
|
double precision, dimension(3), intent(in) | axis, |
|
|
double precision, intent(in) | angle ) |
Compose by a rotation matrix. Refer to the code to see the coefficients. Note that the axis
can be a non-unit vector. It is normalized in the routine. A null axis results in a null rotation, that is the identity matrix.
- Parameters
-
[in,out] | transformation | transformation that receive the transformation |
[in] | axis | rotation axis which will be normalized |
[in] | angle | angle of rotation in radians |
◆ cg_transformation_add_rotation_cos_sin()
pure subroutine mod_cg_transformation::cg_transformation_add_rotation_cos_sin |
( |
class(t_cg_transformation), intent(inout) | transformation, |
|
|
double precision, dimension(3), intent(in) | axis, |
|
|
double precision, intent(in) | c, |
|
|
double precision, intent(in) | s ) |
Compose by a rotation matrix. Refer to the code to see the coefficients. Note that the axis
can be a non-unit vector. It is normalized in the routine. A null axis results in a null rotation, that is the identity matrix.
- Parameters
-
[in,out] | transformation | transformation that receive the transformation |
[in] | axis | rotation axis which will be normalized |
[in] | c,s | cosine and sine of the angle of rotation |
◆ cg_transformation_add_rotation_x()
pure subroutine mod_cg_transformation::cg_transformation_add_rotation_x |
( |
class(t_cg_transformation), intent(inout) | transformation, |
|
|
double precision, intent(in) | angle ) |
Compose by the following rotation matrix:
!! ┌─────┬─────┬─────┬─────┐
!! │ 1 │ 0 │ 0 │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ c │ -s │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ s │ c │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 0 │ 0 │ 1 │
!! └─────┴─────┴─────┴─────┘
!!
Where s and c are the sine and the cosine of the angle
.
- Warning
- Do not apply this transformation in 2D
- Parameters
-
[in,out] | transformation | transformation that receive the transformation |
[in] | angle | angle of rotation in radians |
◆ cg_transformation_add_rotation_y()
pure subroutine mod_cg_transformation::cg_transformation_add_rotation_y |
( |
class(t_cg_transformation), intent(inout) | transformation, |
|
|
double precision, intent(in) | angle ) |
Compose by the following rotation matrix:
!! ┌─────┬─────┬─────┬─────┐
!! │ c │ 0 │ s │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 1 │ 0 │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ -s │ 0 │ c │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 0 │ 0 │ 1 │
!! └─────┴─────┴─────┴─────┘
!!
Where s and c are the sine and the cosine of the angle
.
- Warning
- Do not apply this transformation in 2D
- Parameters
-
[in,out] | transformation | transformation that receive the transformation |
[in] | angle | angle of rotation in radians |
◆ cg_transformation_add_rotation_z()
pure subroutine mod_cg_transformation::cg_transformation_add_rotation_z |
( |
class(t_cg_transformation), intent(inout) | transformation, |
|
|
double precision, intent(in) | angle ) |
Compose by the following rotation matrix:
!! ┌─────┬─────┬─────┬─────┐
!! │ c │ -s │ 0 │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ s │ c │ 0 │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 0 │ 1 │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 0 │ 0 │ 1 │
!! └─────┴─────┴─────┴─────┘
!!
Where s and c are the sine and the cosine of the angle
.
- Parameters
-
[in,out] | transformation | transformation that receive the transformation |
[in] | angle | angle of rotation in radians |
◆ cg_transformation_add_scale()
pure subroutine mod_cg_transformation::cg_transformation_add_scale |
( |
class(t_cg_transformation), intent(inout) | transformation, |
|
|
double precision, dimension(:), intent(in) | vector ) |
Compose by the following translation matrix:
!! ┌─────┬─────┬─────┬─────┐
!! │ sx │ 0 │ 0 │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ sy │ 0 │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 0 │ sz │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 0 │ 0 │ 1 │
!! └─────┴─────┴─────┴─────┘
!!
Where sx, sy, and sz are the scaling factor in direction x, y, and z.
- Parameters
-
[in,out] | transformation | transformation that receive the transformation |
[in] | vector | array containing the scaling factors per direction. |
◆ cg_transformation_add_scale_x()
pure subroutine mod_cg_transformation::cg_transformation_add_scale_x |
( |
class(t_cg_transformation), intent(inout) | transformation, |
|
|
double precision, intent(in) | factor ) |
Compose by the following translation matrix:
!! ┌─────┬─────┬─────┬─────┐
!! │ sx │ 0 │ 0 │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 1 │ 0 │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 0 │ 1 │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 0 │ 0 │ 1 │
!! └─────┴─────┴─────┴─────┘
!!
Where sx is the scale factor in the direction x.
- Parameters
-
[in,out] | transformation | transformation that receive the transformation |
[in] | factor | scaling factor in direction x. |
◆ cg_transformation_add_scale_y()
pure subroutine mod_cg_transformation::cg_transformation_add_scale_y |
( |
class(t_cg_transformation), intent(inout) | transformation, |
|
|
double precision, intent(in) | factor ) |
Compose by the following translation matrix:
!! ┌─────┬─────┬─────┬─────┐
!! │ 1 │ 0 │ 0 │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ sy │ 0 │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 0 │ 1 │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 0 │ 0 │ 1 │
!! └─────┴─────┴─────┴─────┘
!!
Where sy is the scale factor in the direction y.
- Parameters
-
[in,out] | transformation | transformation that receive the transformation |
[in] | factor | scaling factor in direction y. |
◆ cg_transformation_add_scale_z()
pure subroutine mod_cg_transformation::cg_transformation_add_scale_z |
( |
class(t_cg_transformation), intent(inout) | transformation, |
|
|
double precision, intent(in) | factor ) |
Compose by the following translation matrix:
!! ┌─────┬─────┬─────┬─────┐
!! │ 1 │ 0 │ 0 │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 1 │ 0 │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 0 │ sz │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 0 │ 0 │ 1 │
!! └─────┴─────┴─────┴─────┘
!!
Where sz is the scale factor in the direction z.
- Warning
- Do not apply this transformation in 2D
- Parameters
-
[in,out] | transformation | transformation that receive the transformation |
[in] | factor | scaling factor in direction z. |
◆ cg_transformation_add_translation()
pure subroutine mod_cg_transformation::cg_transformation_add_translation |
( |
class(t_cg_transformation), intent(inout) | transformation, |
|
|
double precision, dimension(:), intent(in) | vector ) |
Compose by the following translation matrix:
!! ┌─────┬─────┬─────┬─────┐
!! │ 1 │ 0 │ 0 │ tx │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 1 │ 0 │ ty │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 0 │ 1 │ tz │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 0 │ 0 │ 1 │
!! └─────┴─────┴─────┴─────┘
!!
Where tx, ty, tz are the coordinates of the translation vector
.
- Parameters
-
[in,out] | transformation | transformation that receive the transformation |
[in] | vector | translation vector |
◆ cg_transformation_compose()
Add a transformation to an other. Perform a matrix-matrix product.
- Parameters
-
[in] | transformation | transformation to add |
[in,out] | target | transformation that receive the transformation |
◆ cg_transformation_initialize()
pure subroutine mod_cg_transformation::cg_transformation_initialize |
( |
class(t_cg_transformation), intent(inout) | transformation, |
|
|
integer, intent(in) | dimension ) |
The initialization results in the following matrix:
!! ┌─────┬─────┬─────┬─────┐
!! │ 1 │ 0 │ 0 │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 1 │ 0 │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 0 │ 1 │ 0 │
!! ├─────┼─────┼─────┼─────┤
!! │ 0 │ 0 │ 0 │ 1 │
!! └─────┴─────┴─────┴─────┘
!!
- Parameters
-
[in,out] | transformation | transformation |
[in] | dimension | spatial dimension |