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 mut x = p.x * self.scale_x;
100 let mut y = p.y * self.scale_y;
101
102 if self.rotate != 0.0 {
103 let cos = self.rotate.cos();
104 let sin = self.rotate.sin();
105 let nx = x * cos - y * sin;
106 let ny = x * sin + y * cos;
107 x = nx;
108 y = ny;
109 }
110
111 Vec2 {
112 x: x + self.translate_x,
113 y: y + self.translate_y,
114 }
115 }
116
117 pub fn apply_to_rect(&self, r: Rect) -> Rect {
118 let corners = [
119 Vec2 { x: r.x, y: r.y },
120 Vec2 {
121 x: r.x + r.w,
122 y: r.y,
123 },
124 Vec2 {
125 x: r.x,
126 y: r.y + r.h,
127 },
128 Vec2 {
129 x: r.x + r.w,
130 y: r.y + r.h,
131 },
132 ];
133 let mut min_x = f32::MAX;
134 let mut min_y = f32::MAX;
135 let mut max_x = f32::MIN;
136 let mut max_y = f32::MIN;
137 for c in corners {
138 let p = self.apply_to_point(c);
139 min_x = min_x.min(p.x);
140 min_y = min_y.min(p.y);
141 max_x = max_x.max(p.x);
142 max_y = max_y.max(p.y);
143 }
144 Rect {
145 x: min_x,
146 y: min_y,
147 w: max_x - min_x,
148 h: max_y - min_y,
149 }
150 }
151
152 pub fn combine(&self, other: &Transform) -> Transform {
163 let c = self.rotate.cos();
164 let s = self.rotate.sin();
165
166 Transform {
167 translate_x: other.translate_x * self.scale_x * c
168 - other.translate_y * self.scale_y * s
169 + self.translate_x,
170 translate_y: other.translate_x * self.scale_x * s
171 + other.translate_y * self.scale_y * c
172 + self.translate_y,
173 scale_x: self.scale_x * other.scale_x,
174 scale_y: self.scale_y * other.scale_y,
175 rotate: self.rotate + other.rotate,
176 origin_x: self.origin_x,
177 origin_y: self.origin_y,
178 }
179 }
180}