Skip to main content

repose_core/
geometry.rs

1#[derive(Clone, Copy, Debug, Default, PartialEq)]
2pub struct Vec2 {
3    pub x: f32,
4    pub y: f32,
5}
6
7#[derive(Clone, Copy, Debug, Default, PartialEq)]
8pub struct Size {
9    pub width: f32,
10    pub height: f32,
11}
12
13#[derive(Clone, Copy, Debug, Default, PartialEq)]
14pub struct Rect {
15    pub x: f32,
16    pub y: f32,
17    pub w: f32,
18    pub h: f32,
19}
20
21impl Rect {
22    pub fn contains(&self, p: Vec2) -> bool {
23        p.x >= self.x && p.x <= self.x + self.w && p.y >= self.y && p.y <= self.y + self.h
24    }
25}
26
27#[derive(Clone, Copy, Debug, Default, PartialEq)]
28pub struct Transform {
29    pub translate_x: f32,
30    pub translate_y: f32,
31    pub scale_x: f32,
32    pub scale_y: f32,
33    pub rotate: f32, // radians
34}
35
36impl Transform {
37    pub fn identity() -> Self {
38        Self {
39            translate_x: 0.0,
40            translate_y: 0.0,
41            scale_x: 1.0,
42            scale_y: 1.0,
43            rotate: 0.0,
44        }
45    }
46
47    pub fn translate(x: f32, y: f32) -> Self {
48        Self {
49            translate_x: x,
50            translate_y: y,
51            scale_x: 1.0,
52            scale_y: 1.0,
53            rotate: 0.0,
54        }
55    }
56
57    pub fn apply_to_point(&self, p: Vec2) -> Vec2 {
58        // Apply in order: scale, rotate, translate
59        let mut x = p.x * self.scale_x;
60        let mut y = p.y * self.scale_y;
61
62        if self.rotate != 0.0 {
63            let cos = self.rotate.cos();
64            let sin = self.rotate.sin();
65            let nx = x * cos - y * sin;
66            let ny = x * sin + y * cos;
67            x = nx;
68            y = ny;
69        }
70
71        Vec2 {
72            x: x + self.translate_x,
73            y: y + self.translate_y,
74        }
75    }
76
77    pub fn apply_to_rect(&self, r: Rect) -> Rect {
78        let corners = [
79            Vec2 { x: r.x, y: r.y },
80            Vec2 {
81                x: r.x + r.w,
82                y: r.y,
83            },
84            Vec2 {
85                x: r.x,
86                y: r.y + r.h,
87            },
88            Vec2 {
89                x: r.x + r.w,
90                y: r.y + r.h,
91            },
92        ];
93        let mut min_x = f32::MAX;
94        let mut min_y = f32::MAX;
95        let mut max_x = f32::MIN;
96        let mut max_y = f32::MIN;
97        for c in corners {
98            let p = self.apply_to_point(c);
99            min_x = min_x.min(p.x);
100            min_y = min_y.min(p.y);
101            max_x = max_x.max(p.x);
102            max_y = max_y.max(p.y);
103        }
104        Rect {
105            x: min_x,
106            y: min_y,
107            w: max_x - min_x,
108            h: max_y - min_y,
109        }
110    }
111
112    pub fn combine(&self, other: &Transform) -> Transform {
113        Transform {
114            translate_x: self.translate_x + other.translate_x,
115            translate_y: self.translate_y + other.translate_y,
116            scale_x: self.scale_x * other.scale_x,
117            scale_y: self.scale_y * other.scale_y,
118            rotate: self.rotate + other.rotate,
119        }
120    }
121}