geometry/
corner.rs

1//! Describes the corners of axis-aligned rectangles.
2//!
3//! # Examples
4//!
5//! You can access the corners of a [`Rect`](crate::rect::Rect):
6//!
7//! ```
8//! # use geometry::prelude::*;
9//! let rect = Rect::from_sides(10, 20, 30, 40);
10//! assert_eq!(rect.corner(Corner::LowerRight), Point::new(30, 20));
11//! ```
12//!
13//! You can also increase the size of a [`Rect`](crate::rect::Rect) by pushing out one of its corners:
14//!
15//! ```
16//! # use geometry::prelude::*;
17//! let rect = Rect::from_sides(10, 20, 30, 40);
18//! assert_eq!(rect.expand_corner(Corner::UpperLeft, 100), Rect::from_sides(-90, 20, 30, 140));
19//! ```
20
21use array_map::Indexable;
22use serde::{Deserialize, Serialize};
23
24use crate::dir::Dir;
25use crate::side::Side;
26
27/// An enumeration of the corners of an axis-aligned rectangle.
28///
29/// See the [module-level documentation](crate::corner) for examples.
30#[derive(Debug, Clone, Copy, Serialize, Deserialize, Hash, PartialEq, Eq)]
31#[repr(u8)]
32#[derive(Indexable)]
33pub enum Corner {
34    /// The lower-left corner.
35    LowerLeft,
36    /// The lower-right corner.
37    LowerRight,
38    /// The upper-left corner.
39    UpperLeft,
40    /// The upper-right corner.
41    UpperRight,
42}
43
44impl Corner {
45    /// Gets the [`Side`] corresponding to the given [`Dir`] for this corner.
46    ///
47    /// # Example
48    ///
49    /// ```
50    /// # use geometry::prelude::*;
51    /// assert_eq!(Corner::LowerLeft.side(Dir::Horiz), Side::Left);
52    /// assert_eq!(Corner::LowerLeft.side(Dir::Vert), Side::Bot);
53    /// assert_eq!(Corner::LowerRight.side(Dir::Horiz), Side::Right);
54    /// assert_eq!(Corner::LowerRight.side(Dir::Vert), Side::Bot);
55    /// assert_eq!(Corner::UpperLeft.side(Dir::Horiz), Side::Left);
56    /// assert_eq!(Corner::UpperLeft.side(Dir::Vert), Side::Top);
57    /// assert_eq!(Corner::UpperRight.side(Dir::Horiz), Side::Right);
58    /// assert_eq!(Corner::UpperRight.side(Dir::Vert), Side::Top);
59    /// ```
60    pub fn side(&self, dir: Dir) -> Side {
61        use Corner::*;
62        use Dir::*;
63        use Side::*;
64        match dir {
65            Horiz => match self {
66                LowerLeft | UpperLeft => Left,
67                LowerRight | UpperRight => Right,
68            },
69            Vert => match self {
70                LowerLeft | LowerRight => Bot,
71                UpperLeft | UpperRight => Top,
72            },
73        }
74    }
75}