use super::*;
mod constructors;
mod arith;
#[cfg_attr(feature = "serde", repr(C), derive(Serialize, Deserialize))]
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct Rectangle<T> {
pub min: Point<T>,
pub max: Point<T>,
}
impl<T> Shape2D for Rectangle<T>
where
T: Signed + Clone + PartialOrd,
{
type Value = T;
type VertexIterator<'a>
= IntoIter<Point<T>>where
T: 'a;
type LineIterator<'a>
= IntoIter<Line<T>>where
T: 'a;
fn is_valid(&self) -> bool {
self.max.x > self.min.x && self.max.y > self.min.y
}
fn normalize(&mut self) -> bool {
*self = self.boundary();
self.is_valid()
}
fn boundary(&self) -> Rectangle<Self::Value> {
let min_x = min2(&self.min.x, &self.max.x).clone();
let min_y = min2(&self.min.y, &self.max.y).clone();
let max_x = max2(&self.max.x, &self.min.x).clone();
let max_y = max2(&self.max.y, &self.min.y).clone();
Rectangle { min: Point { x: min_x, y: min_y }, max: Point { x: max_x, y: max_y } }
}
fn vertices<'a>(&'a self, _: usize) -> Self::VertexIterator<'a> {
vec![
self.min.clone(),
Point { x: self.max.x.clone(), y: self.min.y.clone() },
self.max.clone(),
Point { x: self.min.x.clone(), y: self.max.y.clone() },
]
.into_iter()
}
fn edges<'a>(&'a self, _: usize) -> Self::LineIterator<'a> {
let mut start = self.min.clone();
let mut end = Point { x: self.max.x.clone(), y: self.min.y.clone() };
let mut out = Vec::with_capacity(4);
{
out.push(Line::new(start.clone(), end.clone()));
start = end.clone();
end = self.max.clone();
out.push(Line::new(start.clone(), end.clone()));
start = end.clone();
end = Point { x: self.min.x.clone(), y: self.max.y.clone() };
out.push(Line::new(start.clone(), end.clone()));
start = end.clone();
end = self.min.clone();
out.push(Line::new(start.clone(), end.clone()));
};
out.into_iter()
}
}
impl<T> Rectangle<T> {
pub fn width(&self) -> T
where
T: Clone + Sub<Output = T>,
{
self.max.x.clone() - self.min.x.clone()
}
pub fn height(&self) -> T
where
T: Clone + Sub<Output = T>,
{
self.max.y.clone() - self.min.y.clone()
}
pub fn origin(&self) -> Point<T>
where
T: Clone,
{
self.min.clone()
}
pub fn center(&self) -> Point<T>
where
T: Clone + One + Add<Output = T> + Sub<Output = T> + Div<Output = T>,
{
Point { x: (self.min.x.clone() + self.max.x.clone()) / two(), y: (self.min.y.clone() + self.max.y.clone()) / two() }
}
pub fn ref_inner(&self) -> Rectangle<&T> {
Rectangle { min: self.min.ref_inner(), max: self.max.ref_inner() }
}
pub fn contains(&self, point: &Point<T>) -> bool
where
T: Clone + PartialOrd,
{
point.x >= self.min.x.clone()
&& point.x <= self.max.x.clone()
&& point.y >= self.min.y.clone()
&& point.y <= self.max.y.clone()
}
pub fn overlaps(&self, other: &Rectangle<T>) -> bool
where
T: Clone + PartialOrd,
{
self.min.x.clone() <= other.max.x.clone()
&& self.max.x.clone() >= other.min.x.clone()
&& self.min.y.clone() <= other.max.y.clone()
&& self.max.y.clone() >= other.min.y.clone()
}
pub fn area(&self) -> T
where
T: Clone + Mul<Output = T> + Sub<Output = T>,
{
(self.max.x.clone() - self.min.x.clone()) * (self.max.y.clone() - self.min.y.clone())
}
}