Skip to main content

agg_gui/
geometry.rs

1//! Basic 2D geometry types.
2//!
3//! All coordinates are in first-quadrant (Y-up) space unless otherwise noted.
4//! Origin is bottom-left. Positive Y goes upward.
5
6/// A 2D point in first-quadrant (Y-up) coordinates.
7#[derive(Clone, Copy, Debug, Default, PartialEq)]
8pub struct Point {
9    pub x: f64,
10    pub y: f64,
11}
12
13impl Point {
14    pub const ORIGIN: Self = Self { x: 0.0, y: 0.0 };
15
16    pub const fn new(x: f64, y: f64) -> Self {
17        Self { x, y }
18    }
19}
20
21/// A 2D size (width × height), always non-negative.
22#[derive(Clone, Copy, Debug, Default, PartialEq)]
23pub struct Size {
24    pub width: f64,
25    pub height: f64,
26}
27
28impl Size {
29    pub const ZERO: Self = Self {
30        width: 0.0,
31        height: 0.0,
32    };
33
34    /// A very large size used as the default `max_size` in [`WidgetBase`].
35    ///
36    /// Uses `f64::MAX / 2` rather than `f64::MAX` so that summing sizes with
37    /// margins or gaps never overflows to infinity.
38    pub const MAX: Self = Self {
39        width: f64::MAX / 2.0,
40        height: f64::MAX / 2.0,
41    };
42
43    pub const fn new(width: f64, height: f64) -> Self {
44        Self { width, height }
45    }
46}
47
48/// An axis-aligned rectangle in first-quadrant (Y-up) coordinates.
49///
50/// `(x, y)` is the bottom-left corner. Width and height are positive.
51#[derive(Clone, Copy, Debug, Default, PartialEq)]
52pub struct Rect {
53    pub x: f64,
54    pub y: f64,
55    pub width: f64,
56    pub height: f64,
57}
58
59impl Rect {
60    pub const fn new(x: f64, y: f64, width: f64, height: f64) -> Self {
61        Self {
62            x,
63            y,
64            width,
65            height,
66        }
67    }
68
69    pub fn left(&self) -> f64 {
70        self.x
71    }
72    pub fn bottom(&self) -> f64 {
73        self.y
74    }
75    pub fn right(&self) -> f64 {
76        self.x + self.width
77    }
78    pub fn top(&self) -> f64 {
79        self.y + self.height
80    }
81
82    pub fn center(&self) -> Point {
83        Point::new(self.x + self.width * 0.5, self.y + self.height * 0.5)
84    }
85
86    pub fn contains(&self, p: Point) -> bool {
87        p.x >= self.x && p.x <= self.right() && p.y >= self.y && p.y <= self.top()
88    }
89}