1#[derive(Debug, Clone, Copy)]
5pub struct Matrix3x3 {
6 pub m: [[f32; 3]; 3],
8}
9
10impl Matrix3x3 {
11 pub fn identity() -> Self {
13 Self {
14 m: [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]],
15 }
16 }
17
18 pub fn translate(x: f32, y: f32) -> Self {
20 Self {
21 m: [[1.0, 0.0, x], [0.0, 1.0, y], [0.0, 0.0, 1.0]],
22 }
23 }
24
25 pub fn scale(sx: f32, sy: f32) -> Self {
27 Self {
28 m: [[sx, 0.0, 0.0], [0.0, sy, 0.0], [0.0, 0.0, 1.0]],
29 }
30 }
31
32 pub fn rotate(angle: f32) -> Self {
34 let cos = angle.cos();
35 let sin = angle.sin();
36 Self {
37 m: [[cos, -sin, 0.0], [sin, cos, 0.0], [0.0, 0.0, 1.0]],
38 }
39 }
40
41 pub fn multiply(&self, other: &Self) -> Self {
43 let mut result = Self::identity();
44 for i in 0..3 {
45 for j in 0..3 {
46 result.m[i][j] = 0.0;
47 for k in 0..3 {
48 result.m[i][j] += self.m[i][k] * other.m[k][j];
49 }
50 }
51 }
52 result
53 }
54
55 pub fn transform_point(&self, x: f32, y: f32) -> (f32, f32) {
57 let tx = self.m[0][0] * x + self.m[0][1] * y + self.m[0][2];
58 let ty = self.m[1][0] * x + self.m[1][1] * y + self.m[1][2];
59 (tx, ty)
60 }
61}
62
63impl Default for Matrix3x3 {
64 fn default() -> Self {
65 Self::identity()
66 }
67}
68
69#[derive(Debug, Clone, Copy)]
71pub struct Transform2D {
72 pub tx: f32,
74 pub ty: f32,
76 pub sx: f32,
78 pub sy: f32,
80 pub rotation: f32,
82 pub shear_x: f32,
84 pub shear_y: f32,
86}
87
88impl Transform2D {
89 pub fn identity() -> Self {
91 Self {
92 tx: 0.0,
93 ty: 0.0,
94 sx: 1.0,
95 sy: 1.0,
96 rotation: 0.0,
97 shear_x: 0.0,
98 shear_y: 0.0,
99 }
100 }
101
102 pub fn to_matrix(&self) -> Matrix3x3 {
104 let translate = Matrix3x3::translate(self.tx, self.ty);
105 let scale = Matrix3x3::scale(self.sx, self.sy);
106 let rotate = Matrix3x3::rotate(self.rotation);
107
108 translate.multiply(&rotate).multiply(&scale)
109 }
110
111 pub fn lerp(&self, other: &Self, t: f32) -> Self {
113 Self {
114 tx: lerp(self.tx, other.tx, t),
115 ty: lerp(self.ty, other.ty, t),
116 sx: lerp(self.sx, other.sx, t),
117 sy: lerp(self.sy, other.sy, t),
118 rotation: lerp(self.rotation, other.rotation, t),
119 shear_x: lerp(self.shear_x, other.shear_x, t),
120 shear_y: lerp(self.shear_y, other.shear_y, t),
121 }
122 }
123}
124
125impl Default for Transform2D {
126 fn default() -> Self {
127 Self::identity()
128 }
129}
130
131pub fn lerp(a: f32, b: f32, t: f32) -> f32 {
133 a + (b - a) * t
134}
135
136pub fn cubic_bezier(t: f32, p1: f32, p2: f32) -> f32 {
138 let t2 = t * t;
141 let t3 = t2 * t;
142 let mt = 1.0 - t;
143 let mt2 = mt * mt;
144 let mt3 = mt2 * mt;
145
146 mt3 * 0.0 + 3.0 * mt2 * t * p1 + 3.0 * mt * t2 * p2 + t3 * 1.0
147}