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