logo
pub struct AffineTransform<T: CoordNum = f64>(_);
Expand description

A general affine transformation matrix, and associated operations.

Note that affine ops are already implemented on most geo-types primitives, using this module.

Affine transforms using the same numeric type (e.g. CoordFloat) can be composed, and the result can be applied to geometries using e.g. MapCoords. This allows the efficient application of transforms: an arbitrary number of operations can be chained. These are then composed, producing a final transformation matrix which is applied to the geometry coordinates.

AffineTransform is a row-major matrix. 2D affine transforms require six matrix parameters:

[a, b, xoff, d, e, yoff]

these map onto the AffineTransform rows as follows:

[[a, b, xoff],
[d, e, yoff],
[0, 0, 1]]

The equations for transforming coordinates (x, y) -> (x', y') are given as follows:

x' = ax + by + xoff

y' = dx + ey + yoff

Usage

Two types of operation are provided: construction and mutation. Construction functions create a new transform and are denoted by the use of the present tense: scale(), translate(), rotate(), and skew().

Mutation methods add a transform to the existing AffineTransform, and are denoted by the use of the past participle: scaled(), translated(), rotated(), and skewed().

Examples

Build up transforms by beginning with a constructor, then chaining mutation operations

use geo::{AffineOps, AffineTransform};
use geo::{line_string, BoundingRect, Point, LineString};
use approx::assert_relative_eq;

let ls: LineString = line_string![
    (x: 0.0f64, y: 0.0f64),
    (x: 0.0f64, y: 10.0f64),
];
let center = ls.bounding_rect().unwrap().center();

let transform = AffineTransform::skew(40.0, 40.0, center).rotated(45.0, center);

let skewed_rotated = ls.affine_transform(&transform);

assert_relative_eq!(skewed_rotated, line_string![
    (x: 0.5688687f64, y: 4.4311312),
    (x: -0.5688687, y: 5.5688687)
], max_relative = 1.0);

Implementations

Create a new affine transformation by composing two AffineTransforms.

This is a cumulative operation; the new transform is added to the existing transform.

Create the identity matrix

The matrix is:

[[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]

Whether the transformation is equivalent to the identity matrix, that is, whether it’s application will be a a no-op.

use geo::AffineTransform;
let mut transform = AffineTransform::identity();
assert!(transform.is_identity());

// mutate the transform a bit
transform = transform.translated(1.0, 2.0);
assert!(!transform.is_identity());

// put it back
transform = transform.translated(-1.0, -2.0);
assert!(transform.is_identity());

Create a new affine transform for scaling, scaled by factors along the x and y dimensions. The point of origin is usually given as the 2D bounding box centre of the geometry, but any coordinate may be specified. Negative scale factors will mirror or reflect coordinates.

The matrix is:

[[xfact, 0, xoff],
[0, yfact, yoff],
[0, 0, 1]]

xoff = origin.x - (origin.x * xfact)
yoff = origin.y - (origin.y * yfact)

Add an affine transform for scaling, scaled by factors along the x and y dimensions. The point of origin is usually given as the 2D bounding box centre of the geometry, but any coordinate may be specified. Negative scale factors will mirror or reflect coordinates. This is a cumulative operation; the new transform is added to the existing transform.

Create an affine transform for translation, shifted by offsets along the x and y dimensions.

The matrix is:

[[1, 0, xoff],
[0, 1, yoff],
[0, 0, 1]]

Add an affine transform for translation, shifted by offsets along the x and y dimensions

This is a cumulative operation; the new transform is added to the existing transform.

Apply the current transform to a coordinate

Create a new custom transform matrix

The argument order matches that of the affine transform matrix:

 [[a, b, xoff],
 [d, e, yoff],
 [0, 0, 1]] <-- not part of the input arguments

Create an affine transform for rotation, using an arbitrary point as its centre.

Note that this operation is only available for geometries with floating point coordinates.

angle is given in degrees.

The matrix (angle denoted as theta) is:

[[cos_theta, -sin_theta, xoff],
[sin_theta, cos_theta, yoff],
[0, 0, 1]]

xoff = origin.x - (origin.x * cos(theta)) + (origin.y * sin(theta))
yoff = origin.y - (origin.x * sin(theta)) + (origin.y * cos(theta))

Add an affine transform for rotation, using an arbitrary point as its centre.

Note that this operation is only available for geometries with floating point coordinates.

angle is given in degrees.

This is a cumulative operation; the new transform is added to the existing transform.

Create an affine transform for skewing.

Note that this operation is only available for geometries with floating point coordinates.

Geometries are sheared by angles along x (xs) and y (ys) dimensions. The point of origin is usually given as the 2D bounding box centre of the geometry, but any coordinate may be specified. Angles are given in degrees. The matrix is:

[[1, tan(x), xoff],
[tan(y), 1, yoff],
[0, 0, 1]]

xoff = -origin.y * tan(xs)
yoff = -origin.x * tan(ys)

Add an affine transform for skewing.

Note that this operation is only available for geometries with floating point coordinates.

Geometries are sheared by angles along x (xs) and y (ys) dimensions. The point of origin is usually given as the 2D bounding box centre of the geometry, but any coordinate may be specified. Angles are given in degrees.

This is a cumulative operation; the new transform is added to the existing transform.

Trait Implementations

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Formats the value using the given formatter. Read more

Returns the “default value” for a type. Read more

Converts to this type from the input type.

Converts to this type from the input type.

This method tests for self and other values to be equal, and is used by ==. Read more

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The resulting type after obtaining ownership.

Creates owned data from borrowed data, usually by cloning. Read more

Uses borrowed data to replace owned data, usually by cloning. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.