1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
//! //! Ported from [elm-lang's Transform2D module] //! (https://github.com/elm-lang/core/blob/62b22218c42fb8ccc996c86bea450a14991ab815/src/Transform2D.elm) //! //! //! A library for performing 2D matrix transformations. It is used primarily with the //! `group_transform` function from the `form` module and allows you to do things like rotation, //! scaling, translation, shearing and reflection. //! //! Note that all the matrices in this library are 3*3 matrices of homogeneous coordinates, used //! for affine transformations. Since the bottom row is always `0 0 1` in these matrices, it is //! omitted in the diagrams below. //! use vecmath::{mat2x3_id, Matrix2x3, row_mat2x3_mul}; pub type Matrix2d = Matrix2x3<f64>; /// Represents a 2D transform. #[derive(Clone, Debug)] pub struct Transform2D(pub Matrix2d); impl Transform2D { /// Multiply two transforms together. /// /// ma mb mx na nb nx /// mc md my . nc nd ny /// 0 0 1 0 0 1 /// #[inline] pub fn multiply(self, other: Transform2D) -> Transform2D { let (Transform2D(m), Transform2D(n)) = (self, other); Transform2D(row_mat2x3_mul(m, n)) } } /// Create an identity transform. Transforming by the identity does not change anything, but it can /// come in handy as a default or base case. /// /// 1 0 0 /// 0 1 0 /// #[inline] pub fn identity() -> Transform2D { Transform2D(mat2x3_id()) } /// Creates a transformation matrix. This lets you create transforms such as scales, shears, /// reflections and translations. /// /// a b x /// c d y /// #[inline] pub fn matrix(a: f64, b: f64, c: f64, d: f64, x: f64, y: f64) -> Transform2D { Transform2D([ [a, b, x], [c, d, y] ]) } /// Create a [rotation matrix](http://en.wikipedia.org/wiki/Rotation_matrix). Given an angle t, it /// creates a counterclockwise rotation matrix. /// /// cos t -sin t 0 /// sin t cos t 0 /// #[inline] pub fn rotation(t: f64) -> Transform2D { Transform2D([ [t.cos(), -t.sin(), 0.0], [t.sin(), t.cos(), 0.0] ]) } /// Creates a transformation matrix for translation. /// /// 1 0 x /// 0 1 y /// #[inline] pub fn translation(x: f64, y: f64) -> Transform2D { matrix(1.0, 0.0, 0.0, 1.0, x, y) } /// Creates a transformation matrix for scaling by all directions. /// /// s 0 0 /// 0 s 0 /// #[inline] pub fn scale(s: f64) -> Transform2D { matrix(s, 0.0, 0.0, s, 0.0, 0.0) } /// Creates a transformation for horizontal scaling. #[inline] pub fn scale_x(s: f64) -> Transform2D { matrix(s, 0.0, 0.0, 1.0, 0.0, 0.0) } /// Creates a transformation for vertical scaling. #[inline] pub fn scale_y(s: f64) -> Transform2D { matrix(1.0, 0.0, 0.0, s, 0.0, 0.0) }