Skip to content

Matrix

A 2D affine transformation (a 2×3 matrix), in the layout of CSS and SVG matrix(a, b, c, d, e, f):

x' = a·x + c·y + e
y' = b·x + d·y + f
use helpers4::geometry::Matrix;

Cargo feature geometry (enabled by default). To compile only this module:

cargo add helpers4 --no-default-features --features geometry

or in Cargo.toml:

[dependencies]
helpers4 = { version = "0.0.9", default-features = false, features = ["geometry"] }
pub struct Matrix { /* private fields */ }
use helpers4::geometry::{Matrix, Point};

// Scale by 2, then move by (10, 0): the last matrix of a product applies first.
let scale = Matrix::new(2.0, 0.0, 0.0, 2.0, 0.0, 0.0);
let shift = Matrix::new(1.0, 0.0, 0.0, 1.0, 10.0, 0.0);
let m = shift.multiply(scale);
assert_eq!(m.apply(Point::new(1.0, 1.0)), Point::new(12.0, 2.0));
assert_eq!(m.invert().map(|inv| inv.apply(Point::new(12.0, 2.0))), Some(Point::new(1.0, 1.0)));
pub fn rotate(radians: f64) -> Self

A rotation around the origin. With the y axis pointing down (screens, CSS, SVG), a positive angle turns clockwise, like CSS rotate().

Parameters

ParameterTypeDescription
radiansf64The angle, in radians.

Returns

Self — The matrix.

Examples

use helpers4::geometry::{Matrix, Point};

let p = Matrix::rotate(std::f64::consts::FRAC_PI_2).apply(Point::new(1.0, 0.0));
assert!(p.x.abs() < 1e-12 && (p.y - 1.0).abs() < 1e-12);
pub fn multiply(self, other: Self) -> Self

Multiplies self by other, in the mathematical order: other applies first, then self, as in a CSS transform list (transform: self other).

Parameters

ParameterTypeDescription
otherSelfThe transformation applied first.

Returns

Self — The product, with m.multiply(n).apply(p) == m.apply(n.apply(p)) (up to rounding).

Examples

use helpers4::geometry::{Matrix, Point};

let parent = Matrix::new(1.0, 0.0, 0.0, 1.0, 100.0, 50.0);
let child = Matrix::new(2.0, 0.0, 0.0, 2.0, 0.0, 0.0);
// A child layer's point, in the coordinates of the page
assert_eq!(parent.multiply(child).apply(Point::new(1.0, 1.0)), Point::new(102.0, 52.0));
pub fn invert(self) -> Option<Self>

The matrix that undoes self, e.g. to turn a pointer position into the coordinates of a transformed layer.

A matrix that flattens the plane onto a line or a point (determinant 0) cannot be undone. There is no tolerance: a nearly flat matrix is inverted, with very large entries, as long as they stay finite.

Returns

Option<Self> — The inverse, or None when self cannot be inverted (or has a non-finite entry).

Examples

use helpers4::geometry::Matrix;

let shift = Matrix::new(1.0, 0.0, 0.0, 1.0, 10.0, 5.0);
assert_eq!(shift.invert(), Some(Matrix::new(1.0, 0.0, 0.0, 1.0, -10.0, -5.0)));
assert_eq!(Matrix::new(0.0, 0.0, 0.0, 0.0, 1.0, 1.0).invert(), None);
pub fn to_css(self) -> String

The CSS and SVG transform value, matrix(a, b, c, d, e, f).

Entries are written as Rust prints them, without rounding (and 0 for -0); a non-finite entry gives a value CSS rejects.

Returns

String — For instance "matrix(2, 0, 0, 2, 10, -5)".

Examples

use helpers4::geometry::Matrix;

assert_eq!(Matrix::new(2.0, 0.0, 0.0, 2.0, 10.0, -5.0).to_css(), "matrix(2, 0, 0, 2, 10, -5)");
pub fn apply(self, point: Point) -> Point

Transforms a point.

Parameters

ParameterTypeDescription
pointPointThe point to transform.

Returns

Point — (a·x + c·y + e, b·x + d·y + f).

Examples

use helpers4::geometry::{Matrix, Point};

let m = Matrix::new(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);
assert_eq!(m.apply(Point::new(1.0, 1.0)), Point::new(9.0, 12.0));
pub fn bounding_box(self, rect: Rect) -> Rect

Transforms a rectangle and returns its bounding box: the smallest axis-aligned rectangle containing it. After a rotation or a skew, the box is larger than the rectangle.

Parameters

ParameterTypeDescription
rectRectThe rectangle to transform.

Returns

Rect — The bounding box of the four transformed corners, with a non-negative size.

Examples

use helpers4::geometry::{Matrix, Rect};

let flip = Matrix::new(-2.0, 0.0, 0.0, 1.0, 0.0, 0.0);
assert_eq!(flip.bounding_box(Rect::new(1.0, 0.0, 2.0, 3.0)), Rect::new(-6.0, 0.0, 4.0, 3.0));

src/geometry/matrix.rs