1#[derive(Clone, Copy, Debug, Default, PartialEq)]
2pub struct Vec2 {
3 pub x: f32,
4 pub y: f32,
5}
6
7impl Vec2 {
8 pub const ZERO: Vec2 = Vec2 { x: 0.0, y: 0.0 };
9}
10
11impl std::ops::Add for Vec2 {
12 type Output = Vec2;
13 fn add(self, other: Vec2) -> Vec2 {
14 Vec2 {
15 x: self.x + other.x,
16 y: self.y + other.y,
17 }
18 }
19}
20
21impl std::ops::Sub for Vec2 {
22 type Output = Vec2;
23 fn sub(self, other: Vec2) -> Vec2 {
24 Vec2 {
25 x: self.x - other.x,
26 y: self.y - other.y,
27 }
28 }
29}
30
31impl std::ops::Neg for Vec2 {
32 type Output = Vec2;
33 fn neg(self) -> Vec2 {
34 Vec2 {
35 x: -self.x,
36 y: -self.y,
37 }
38 }
39}
40
41#[derive(Clone, Copy, Debug, Default, PartialEq)]
42pub struct Size {
43 pub width: f32,
44 pub height: f32,
45}
46
47#[derive(Clone, Copy, Debug, Default, PartialEq)]
48pub struct Rect {
49 pub x: f32,
50 pub y: f32,
51 pub w: f32,
52 pub h: f32,
53}
54
55impl Rect {
56 pub fn contains(&self, p: Vec2) -> bool {
57 p.x >= self.x && p.x <= self.x + self.w && p.y >= self.y && p.y <= self.y + self.h
58 }
59}
60
61#[derive(Clone, Copy, Debug, Default, PartialEq)]
62pub struct Transform {
63 pub translate_x: f32,
64 pub translate_y: f32,
65 pub scale_x: f32,
66 pub scale_y: f32,
67 pub rotate: f32, pub origin_x: f32,
69 pub origin_y: f32,
70}
71
72impl Transform {
73 pub fn identity() -> Self {
74 Self {
75 translate_x: 0.0,
76 translate_y: 0.0,
77 scale_x: 1.0,
78 scale_y: 1.0,
79 rotate: 0.0,
80 origin_x: 0.5,
81 origin_y: 0.5,
82 }
83 }
84
85 pub fn translate(x: f32, y: f32) -> Self {
86 Self {
87 translate_x: x,
88 translate_y: y,
89 scale_x: 1.0,
90 scale_y: 1.0,
91 rotate: 0.0,
92 origin_x: 0.5,
93 origin_y: 0.5,
94 }
95 }
96
97 pub fn apply_to_point(&self, p: Vec2) -> Vec2 {
98 let ox = self.origin_x;
99 let oy = self.origin_y;
100 let mut x = (p.x - ox) * self.scale_x;
101 let mut y = (p.y - oy) * self.scale_y;
102
103 if self.rotate != 0.0 {
104 let cos = self.rotate.cos();
105 let sin = self.rotate.sin();
106 let nx = x * cos - y * sin;
107 let ny = x * sin + y * cos;
108 x = nx;
109 y = ny;
110 }
111
112 Vec2 {
113 x: x + ox + self.translate_x,
114 y: y + oy + self.translate_y,
115 }
116 }
117
118 pub fn apply_to_rect(&self, r: Rect) -> Rect {
119 let ox = r.x + r.w * self.origin_x;
120 let oy = r.y + r.h * self.origin_y;
121 let corners = [
122 Vec2 { x: r.x, y: r.y },
123 Vec2 {
124 x: r.x + r.w,
125 y: r.y,
126 },
127 Vec2 {
128 x: r.x,
129 y: r.y + r.h,
130 },
131 Vec2 {
132 x: r.x + r.w,
133 y: r.y + r.h,
134 },
135 ];
136 let mut min_x = f32::MAX;
137 let mut min_y = f32::MAX;
138 let mut max_x = f32::MIN;
139 let mut max_y = f32::MIN;
140 for c in corners {
141 let mut x = (c.x - ox) * self.scale_x;
142 let mut y = (c.y - oy) * self.scale_y;
143 if self.rotate != 0.0 {
144 let cos = self.rotate.cos();
145 let sin = self.rotate.sin();
146 let nx = x * cos - y * sin;
147 let ny = x * sin + y * cos;
148 x = nx;
149 y = ny;
150 }
151 x += ox + self.translate_x;
152 y += oy + self.translate_y;
153 min_x = min_x.min(x);
154 min_y = min_y.min(y);
155 max_x = max_x.max(x);
156 max_y = max_y.max(y);
157 }
158 Rect {
159 x: min_x,
160 y: min_y,
161 w: max_x - min_x,
162 h: max_y - min_y,
163 }
164 }
165
166 pub fn combine(&self, other: &Transform) -> Transform {
177 let c = self.rotate.cos();
178 let s = self.rotate.sin();
179
180 Transform {
181 translate_x: other.translate_x * self.scale_x * c
182 - other.translate_y * self.scale_y * s
183 + self.translate_x,
184 translate_y: other.translate_x * self.scale_x * s
185 + other.translate_y * self.scale_y * c
186 + self.translate_y,
187 scale_x: self.scale_x * other.scale_x,
188 scale_y: self.scale_y * other.scale_y,
189 rotate: self.rotate + other.rotate,
190 origin_x: self.origin_x,
191 origin_y: self.origin_y,
192 }
193 }
194}