use std::ops::{Div, Mul};
use crate::point::Point;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Rectangle {
pub top: f32,
pub right: f32,
pub bottom: f32,
pub left: f32,
}
impl Rectangle {
pub fn zero() -> Rectangle {
Rectangle {
top: 0.0,
right: 0.0,
bottom: 0.0,
left: 0.0,
}
}
pub fn from_size(width: f32, height: f32) -> Rectangle {
Rectangle {
top: 0.0,
right: width,
bottom: height,
left: 0.0,
}
}
pub fn from_xywh(x: f32, y: f32, width: f32, height: f32) -> Rectangle {
Rectangle {
top: y,
right: x + width,
bottom: y + height,
left: x,
}
}
pub fn size(&self) -> (f32, f32) {
(self.width(), self.height())
}
pub fn x(&self) -> f32 {
self.left
}
pub fn y(&self) -> f32 {
self.top
}
pub fn width(&self) -> f32 {
self.right - self.left
}
pub fn height(&self) -> f32 {
self.bottom - self.top
}
pub fn contains(&self, x: f32, y: f32) -> bool {
x >= self.left && x <= self.right && y >= self.top && y <= self.bottom
}
pub fn contains_point(&self, point: &Point) -> bool {
self.contains(point.x, point.y)
}
pub fn contains_rectangle(&self, other: &Rectangle) -> bool {
self.left <= other.left
&& self.right >= other.right
&& self.top <= other.top
&& self.bottom >= other.bottom
}
#[must_use]
pub fn move_by(self, delta: &Point) -> Rectangle {
Rectangle {
top: self.top + delta.y,
right: self.right + delta.x,
bottom: self.bottom + delta.y,
left: self.left + delta.x,
}
}
pub fn normalize(&self) -> Rectangle {
Rectangle {
top: 0.0,
right: self.width(),
bottom: self.height(),
left: 0.0,
}
}
pub fn clamp(&self, other: &Rectangle) -> Rectangle {
Rectangle {
top: self.top.max(other.top),
right: self.right.min(other.right),
bottom: self.bottom.min(other.bottom),
left: self.left.max(other.left),
}
}
pub fn clamp_top(&self, other: &Rectangle) -> Rectangle {
Rectangle {
top: self.top.max(other.top),
..*self
}
}
pub fn clamp_right(&self, other: &Rectangle) -> Rectangle {
Rectangle {
right: self.right.min(other.right),
..*self
}
}
pub fn clamp_bottom(&self, other: &Rectangle) -> Rectangle {
Rectangle {
bottom: self.bottom.min(other.bottom),
..*self
}
}
pub fn clamp_left(&self, other: &Rectangle) -> Rectangle {
Rectangle {
left: self.left.max(other.left),
..*self
}
}
pub fn is_empty(&self) -> bool {
self.width() <= 0.0 || self.height() <= 0.0
}
}
impl Div<f32> for Rectangle {
type Output = Rectangle;
fn div(self, rhs: f32) -> Self::Output {
Rectangle {
top: self.top / rhs,
right: self.right / rhs,
bottom: self.bottom / rhs,
left: self.left / rhs,
}
}
}
impl Mul<f32> for Rectangle {
type Output = Rectangle;
fn mul(self, rhs: f32) -> Self::Output {
Rectangle {
top: self.top * rhs,
right: self.right * rhs,
bottom: self.bottom * rhs,
left: self.left * rhs,
}
}
}