silk.geometry.affine.
Two-dimensional affine transforms: scale, rotation, skew, and translation in one matrix.
When to use#
Use Affine2 to move, scale, rotate, or skew points, vectors, and rectangles in a plane, such
as an SVG transform attribute, a font matrix, or a canvas transform. Use
silk.geometry.matrix for projective (3x3) and three-dimensional (4x4) transforms.
Details#
An affine transform is a Copy struct with six public coefficients, generic over its number
type T. It maps a point (x, y) to (xx * x + xy * y + dx, yx * x + yy * y + dy). The
coefficient order xx, yx, xy, yy, dx, dy is the order of SVG and CSS matrix(a, b, c, d, e,
f), of PDF, and of the OpenType and FreeType font matrices, so fromCoefficients takes those
six numbers as written.
left * right composes two transforms: the result applies right first, then left. So a list
of transforms written left to right, as in SVG, multiplies in the written order. transform *
point maps a silk.geometry.point.Point2, and transform * vector maps a
silk.geometry.vector.Vector2 without the translation. &a == &b compares all six coefficients
when T: Equal.
Gotchas#
rotation and skew take radians. A positive angle turns the positive x axis toward
positive y, which is clockwise in a y-down space such as SVG and counterclockwise in a y-up
space such as a font.
Examples#
Rotate around a point#
import silk.geometry.affine { Affine2 }
import silk.geometry.point { Point2 }
import silk.geometry.vector { Vector2 }
pub fn main() -> i32 {
let pivot = Vector2<f64>.new(10.0, 0.0)
let turn = Affine2<f64>.translation(pivot) * Affine2<f64>.rotation(3.141592653589793)
* Affine2<f64>.translation(-pivot)
let moved = turn * Point2<f64>.new(12.0, 0.0)
if moved.x < 7.999999 || moved.x > 8.000001 || moved.y < -0.000001 || moved.y > 0.000001 {
return 1
}
return 0
}Import as Affine2 with import silk.geometry.affine { Affine2 }.
Public declarations: 1.
Affine2#
pub struct Affine2<T>A two-dimensional affine transform with coefficients of number type T.
When to use#
Use Affine2 for any combination of scale, rotation, skew, reflection, and translation in a
plane.
Details#
The transform maps (x, y) to (xx * x + xy * y + dx, yx * x + yy * y + dy). As a matrix that
multiplies a column vector, it is [xx xy dx; yx yy dy; 0 0 1]. The field order matches SVG and
CSS matrix(a, b, c, d, e, f): a = xx, b = yx, c = xy, d = yy, e = dx, and f = dy.
left * right applies right first, then left. transform * point maps a Point2<T>, and
transform * vector maps a Vector2<T> with no translation. &a == &b compares all six
coefficients when T: Equal.
Field xx#
pub xx: THow much input x adds to output x (SVG a).
Field yx#
pub yx: THow much input x adds to output y (SVG b).
Field xy#
pub xy: THow much input y adds to output x (SVG c).
Field yy#
pub yy: THow much input y adds to output y (SVG d).
Field dx#
pub dx: TThe translation added to output x (SVG e).
Field dy#
pub dy: TThe translation added to output y (SVG f).
Implementation Copy for Affine2<T>#
impl<T: Copy> Copy for Affine2<T>Implementation Affine2<T>#
impl<T> Affine2<T>Associated function new#
pub fn new(xx: T, yx: T, xy: T, yy: T, dx: T, dy: T) -> Affine2<T>Returns the transform with the six coefficients in SVG matrix(a, b, c, d, e, f) order.
Method map#
pub fn map<U>(self: Self, transform: mut fn(T) -> U) -> Affine2<U>Returns a transform whose coefficients are transform applied to each one, in field order.
Implementation Affine2<T>#
impl<T: Copy> Affine2<T>Associated function fromCoefficients#
pub fn fromCoefficients(values: [T; 6]) -> Affine2<T>Returns the transform from six coefficients in SVG matrix(a, b, c, d, e, f) order.
Method coefficients#
pub fn coefficients(self: Self) -> [T; 6]Returns the six coefficients in SVG matrix(a, b, c, d, e, f) order.
Method translationPart#
pub fn translationPart(self: Self) -> Vector2<T>Returns the translation part (dx, dy).
Implementation Affine2<T>#
impl<T: Zero + One> Affine2<T>Associated function identity#
pub fn identity() -> Affine2<T>Returns the transform that maps every point to itself.
Associated function translation#
pub fn translation(offset: Vector2<T>) -> Affine2<T>Returns the transform that moves every point by offset.
Associated function scale#
pub fn scale(x: T, y: T) -> Affine2<T>Returns the transform that multiplies x by x and y by y around the origin.
Details#
A negative factor reflects across the other axis.
Implementation Affine2<T>#
impl<T: Copy + Zero + One + Float + Negate<T>> Affine2<T>Associated function rotation#
pub fn rotation(radians: T) -> Affine2<T>Returns the transform that rotates by radians around the origin.
Details#
A positive angle turns the positive x axis toward positive y. That is clockwise in a y-down
space such as SVG, where it matches rotate(angle) after a degree-to-radian conversion.
Associated function skew#
pub fn skew(x: T, y: T) -> Affine2<T>Returns the transform that skews by x radians along the x axis and y radians along the y
axis.
Details#
The result is [1, tan(y), tan(x), 1, 0, 0]. skew(angle, 0) is SVG skewX(angle) and
skew(0, angle) is SVG skewY(angle), after a degree-to-radian conversion.
Implementation Affine2<T>#
impl<T: Copy + Multiply<T, T> + Subtract<T, T>> Affine2<T>Method determinant#
pub fn determinant(self: Self) -> TReturns xx * yy - yx * xy, the factor by which the transform scales area.
Details#
A negative determinant means the transform reflects. Zero means it is singular: it flattens the plane onto a line or a point and has no inverse.
Implementation Affine2<T>#
impl<
T: Copy + Equal + Zero + One + Float + Add<T, T> + Subtract<T, T> + Multiply<T, T> + Divide<
T,
T
> + Negate<T>,
> Affine2<T>Method inverse#
pub fn inverse(self: Self) -> Option<Affine2<T>>Returns the transform that undoes self, or None when self has no finite inverse.
Details#
None means self is singular or has an infinite or NaN coefficient, or that the inverse has
an infinite or NaN coefficient. Each row is scaled by its largest coefficient before the
determinant is formed, so a valid transform with very large or very small scales does not
overflow or underflow to a false None. No epsilon rejects a small but invertible scale.
Method maxScale#
pub fn maxScale(self: Self) -> TReturns the largest factor by which the transform stretches any vector.
When to use#
Use maxScale to convert a tolerance in device space to user space, such as a
curve-flattening tolerance or a stroke width.
Details#
The result is the largest singular value of the linear part [xx xy; yx yy]; the translation
does not count. A transform with an infinite or NaN linear coefficient gives NaN or infinity.
Method transformRect#
pub fn transformRect(self: Self, bounds: Rect<T>) -> Rect<T>Returns the smallest rectangle that holds the four transformed corners of bounds.
Details#
The result holds the whole transformed rectangle, because an affine transform maps a rectangle to a parallelogram whose corners are the transformed corners. For a rotated or skewed transform it is larger than the transformed shape. To bound a curve exactly, transform the curve first and bound the result.
Gotchas#
An infinite or NaN coefficient or edge can give NaN edges. Test with Rect.isFinite.
Method isFinite#
pub fn isFinite(self: Self) -> boolReturns true when all six coefficients are neither infinite nor NaN.
Implementation Multiply<Affine2<T>, Affine2<T>> for Affine2<T>#
impl<T: Copy + Add<T, T> + Multiply<T, T>> Multiply<Affine2<T>, Affine2<T>> for Affine2<T>Operation multiply#
fn multiply(left: Self, right: Self) -> SelfImplementation Multiply<Point2<T>, Point2<T>> for Affine2<T>#
impl<T: Copy + Add<T, T> + Multiply<T, T>> Multiply<Point2<T>, Point2<T>> for Affine2<T>Operation multiply#
fn multiply(left: Self, right: Point2<T>) -> Point2<T>Implementation Multiply<Vector2<T>, Vector2<T>> for Affine2<T>#
impl<T: Copy + Add<T, T> + Multiply<T, T>> Multiply<Vector2<T>, Vector2<T>> for Affine2<T>Operation multiply#
fn multiply(left: Self, right: Vector2<T>) -> Vector2<T>Implementation Equal for Affine2<T>#
impl<T: Equal> Equal for Affine2<T>Operation equals#
fn equals(left: &Self, right: &Self) -> boolCategory: Geometry.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2.