///|
/// 2D rectangle defined by origin and size
pub struct Rect {
x : Double
y : Double
width : Double
height : Double
} derive(Eq, Debug)
///|
pub extend Rect with Debug::{to_repr}
///|
pub extend Rect with Eq::{not_equal, equal}
///|
/// Create a rectangle
pub fn Rect::new(
x~ : Double,
y~ : Double,
width~ : Double,
height~ : Double,
) -> Rect {
{ x, y, width, height, }
}
///|
/// Get the right edge (x + width)
pub fn Rect::right(self : Rect) -> Double {
self.x + self.width
}
///|
/// Get the bottom edge (y + height)
pub fn Rect::bottom(self : Rect) -> Double {
self.y + self.height
}
///|
/// Check whether this rectangle has no positive area.
pub fn Rect::is_empty(self : Rect) -> Bool {
self.width <= 0.0 || self.height <= 0.0
}
///|
/// Return the overlapping rectangle, if both rectangles overlap with area.
pub fn Rect::intersection(self : Rect, other : Rect) -> Rect? {
let left = self.x.max(other.x)
let top = self.y.max(other.y)
let right = self.right().min(other.right())
let bottom = self.bottom().min(other.bottom())
let width = right - left
let height = bottom - top
guard width > 0.0 && height > 0.0 else { return None }
Some(Rect::new(x=left, y=top, width~, height~))
}
///|
/// Check if a point is inside the rectangle
pub fn Rect::contains(self : Rect, px : Double, py : Double) -> Bool {
!self.is_empty() &&
px >= self.x &&
px < self.right() &&
py >= self.y &&
py < self.bottom()
}
///|
/// 2D size (width and height)
pub struct Size {
width : Double
height : Double
} derive(Eq, Debug)
///|
pub extend Size with Debug::{to_repr}
///|
pub extend Size with Eq::{not_equal, equal}
///|
pub fn Size::new(width~ : Double, height~ : Double) -> Size {
{ width, height, }
}