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 { width: 0.0, height: 0.0 };
30
31    /// A very large size used as the default `max_size` in [`WidgetBase`].
32    ///
33    /// Uses `f64::MAX / 2` rather than `f64::MAX` so that summing sizes with
34    /// margins or gaps never overflows to infinity.
35    pub const MAX: Self = Self { width: f64::MAX / 2.0, height: f64::MAX / 2.0 };
36
37    pub const fn new(width: f64, height: f64) -> Self {
38        Self { width, height }
39    }
40}
41
42/// An axis-aligned rectangle in first-quadrant (Y-up) coordinates.
43///
44/// `(x, y)` is the bottom-left corner. Width and height are positive.
45#[derive(Clone, Copy, Debug, Default, PartialEq)]
46pub struct Rect {
47    pub x: f64,
48    pub y: f64,
49    pub width: f64,
50    pub height: f64,
51}
52
53impl Rect {
54    pub const fn new(x: f64, y: f64, width: f64, height: f64) -> Self {
55        Self { x, y, width, height }
56    }
57
58    pub fn left(&self) -> f64 { self.x }
59    pub fn bottom(&self) -> f64 { self.y }
60    pub fn right(&self) -> f64 { self.x + self.width }
61    pub fn top(&self) -> f64 { self.y + self.height }
62
63    pub fn center(&self) -> Point {
64        Point::new(self.x + self.width * 0.5, self.y + self.height * 0.5)
65    }
66
67    pub fn contains(&self, p: Point) -> bool {
68        p.x >= self.x && p.x <= self.right() && p.y >= self.y && p.y <= self.top()
69    }
70}