graphics/
transformed.rs

1use crate::{
2    math::{multiply, orient, rotate_radians, scale, shear, translate, Matrix2d, Scalar, Vec2d},
3    radians::Radians,
4    Context,
5};
6
7/// Implemented by contexts that can transform.
8pub trait Transformed: Sized {
9    /// Appends transform to the current one.
10    fn append_transform(self, transform: Matrix2d) -> Self;
11
12    /// Prepends transform to the current one.
13    fn prepend_transform(self, transform: Matrix2d) -> Self;
14
15    /// Translate x and y in local coordinates.
16    fn trans(self, x: Scalar, y: Scalar) -> Self;
17
18    /// Rotates degrees in local coordinates.
19    #[inline(always)]
20    fn rot_deg(self, angle: Scalar) -> Self {
21        let pi: Scalar = Radians::_180();
22        self.rot_rad(angle * pi / 180.0)
23    }
24
25    /// Rotate radians in local coordinates.
26    fn rot_rad(self, angle: Scalar) -> Self;
27
28    /// Orients x axis to look at point locally.
29    ///
30    /// Leaves x axis unchanged if the point to
31    /// look at is the origin.
32    fn orient(self, x: Scalar, y: Scalar) -> Self;
33
34    /// Scales in local coordinates.
35    fn scale(self, sx: Scalar, sy: Scalar) -> Self;
36
37    /// Translate position in local coordinates.
38    #[inline(always)]
39    fn trans_pos<P: Into<Vec2d>>(self, pos: P) -> Self {
40        let pos = pos.into();
41        self.trans(pos[0], pos[1])
42    }
43
44    /// Orients x axis to look at point locally.
45    #[inline(always)]
46    fn orient_pos<P: Into<Vec2d>>(self, pos: P) -> Self {
47        let pos = pos.into();
48        self.orient(pos[0], pos[1])
49    }
50
51    /// Scales in local coordinates.
52    fn scale_pos<P: Into<Vec2d>>(self, pos: P) -> Self {
53        let pos = pos.into();
54        self.scale(pos[0], pos[1])
55    }
56
57    /// Scales in both directions in local coordinates.
58    #[inline(always)]
59    fn zoom(self, s: Scalar) -> Self {
60        self.scale(s, s)
61    }
62
63    /// Flips vertically in local coordinates.
64    #[inline(always)]
65    fn flip_v(self) -> Self {
66        self.scale(1.0, -1.0)
67    }
68
69    /// Flips horizontally in local coordinates.
70    #[inline(always)]
71    fn flip_h(self) -> Self {
72        self.scale(-1.0, 1.0)
73    }
74
75    /// Flips horizontally and vertically in local coordinates.
76    #[inline(always)]
77    fn flip_hv(self) -> Self {
78        self.scale(-1.0, -1.0)
79    }
80
81    /// Shears in local coordinates.
82    fn shear(self, x: Scalar, y: Scalar) -> Self;
83
84    /// Shears in local coordinates.
85    #[inline(always)]
86    fn shear_pos<P: Into<Vec2d>>(self, pos: P) -> Self {
87        let pos = pos.into();
88        self.shear(pos[0], pos[1])
89    }
90}
91
92impl Transformed for Matrix2d {
93    #[inline(always)]
94    fn append_transform(self, transform: Matrix2d) -> Self {
95        multiply(self, transform)
96    }
97
98    #[inline(always)]
99    fn prepend_transform(self, transform: Matrix2d) -> Self {
100        multiply(transform, self)
101    }
102
103    #[inline(always)]
104    fn trans(self, x: Scalar, y: Scalar) -> Self {
105        let trans = translate([x, y]);
106        multiply(self, trans)
107    }
108
109    #[inline(always)]
110    fn rot_rad(self, angle: Scalar) -> Self {
111        let rot = rotate_radians(angle);
112        multiply(self, rot)
113    }
114
115    #[inline(always)]
116    fn orient(self, x: Scalar, y: Scalar) -> Self {
117        let orient = orient(x, y);
118        multiply(self, orient)
119    }
120
121    #[inline(always)]
122    fn scale(self, sx: Scalar, sy: Scalar) -> Self {
123        let scale = scale(sx, sy);
124        multiply(self, scale)
125    }
126
127    #[inline(always)]
128    fn shear(self, x: Scalar, y: Scalar) -> Self {
129        let shear = shear([x, y]);
130        multiply(self, shear)
131    }
132}
133
134impl Transformed for Context {
135    #[inline(always)]
136    fn append_transform(mut self, transform: Matrix2d) -> Self {
137        self.transform = self.transform.append_transform(transform);
138        self
139    }
140
141    #[inline(always)]
142    fn prepend_transform(mut self, transform: Matrix2d) -> Self {
143        self.transform = self.transform.prepend_transform(transform);
144        self
145    }
146
147    #[inline(always)]
148    fn trans(mut self, x: Scalar, y: Scalar) -> Self {
149        self.transform = self.transform.trans(x, y);
150        self
151    }
152
153    #[inline(always)]
154    fn rot_rad(mut self, angle: Scalar) -> Self {
155        self.transform = self.transform.rot_rad(angle);
156        self
157    }
158
159    #[inline(always)]
160    fn orient(mut self, x: Scalar, y: Scalar) -> Self {
161        self.transform = self.transform.orient(x, y);
162        self
163    }
164
165    #[inline(always)]
166    fn scale(mut self, sx: Scalar, sy: Scalar) -> Self {
167        self.transform = self.transform.scale(sx, sy);
168        self
169    }
170
171    #[inline(always)]
172    fn shear(mut self, x: Scalar, y: Scalar) -> Self {
173        self.transform = self.transform.shear(x, y);
174        self
175    }
176}