diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-11-23 22:04:08 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-11-23 22:04:08 +0100 |
| commit | 8a88f71cb11565c1a78bd57f02a8df17cb2bf7a0 (patch) | |
| tree | 8802c1ff48e2be118e3872d25bd2f2c1f7a21b4a /src/geom/transform.rs | |
| parent | c77c5a0f0ae6560a03a85e847006c29de9c7ae62 (diff) | |
Transformations
Diffstat (limited to 'src/geom/transform.rs')
| -rw-r--r-- | src/geom/transform.rs | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/geom/transform.rs b/src/geom/transform.rs new file mode 100644 index 00000000..ca44667b --- /dev/null +++ b/src/geom/transform.rs @@ -0,0 +1,73 @@ +use super::*; + +/// A scale-skew-translate transformation. +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Serialize, Deserialize)] +pub struct Transform { + pub sx: Relative, + pub ky: Relative, + pub kx: Relative, + pub sy: Relative, + pub tx: Length, + pub ty: Length, +} + +impl Transform { + /// The identity transformation. + pub const fn identity() -> Self { + Self { + sx: Relative::one(), + ky: Relative::zero(), + kx: Relative::zero(), + sy: Relative::one(), + tx: Length::zero(), + ty: Length::zero(), + } + } + + /// A translation transform. + pub const fn translation(tx: Length, ty: Length) -> Self { + Self { tx, ty, ..Self::identity() } + } + + /// A scaling transform. + pub const fn scaling(sx: Relative, sy: Relative) -> Self { + Self { sx, sy, ..Self::identity() } + } + + /// A rotation transform. + pub fn rotation(angle: Angle) -> Self { + let v = angle.to_rad(); + let cos = Relative::new(v.cos()); + let sin = Relative::new(v.sin()); + Self { + sx: cos, + ky: sin, + kx: -sin, + sy: cos, + ..Self::default() + } + } + + /// Whether this is the identity transformation. + pub fn is_identity(&self) -> bool { + *self == Self::identity() + } + + /// Pre-concatenate another transformation. + pub fn pre_concat(&self, prev: Self) -> Self { + Transform { + sx: self.sx * prev.sx + self.kx * prev.ky, + ky: self.ky * prev.sx + self.sy * prev.ky, + kx: self.sx * prev.kx + self.kx * prev.sy, + sy: self.ky * prev.kx + self.sy * prev.sy, + tx: self.sx.resolve(prev.tx) + self.kx.resolve(prev.ty) + self.tx, + ty: self.ky.resolve(prev.tx) + self.sy.resolve(prev.ty) + self.ty, + } + } +} + +impl Default for Transform { + fn default() -> Self { + Self::identity() + } +} |
