#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Point {
pub x: isize,
pub y: isize,
}
impl Point {
pub const fn new(x: isize, y: isize) -> Self {
Self { x, y }
}
pub fn add(&self, q: &Point) -> Point {
Point::new(self.x + q.x, self.y + q.y)
}
pub fn sub(&self, q: &Point) -> Point {
Point::new(self.x - q.x, self.y - q.y)
}
pub fn mul(&self, k: isize) -> Point {
Point::new(self.x * k, self.y * k)
}
pub fn div(&self, k: isize) -> Point {
Point::new(self.x / k, self.y / k)
}
pub fn inside(&self, r: &Rectangle) -> bool {
r.min.x <= self.x && self.x < r.max.x && r.min.y <= self.y && self.y < r.max.y
}
}
#[derive(Debug, Copy, Clone)]
pub struct Rectangle {
pub min: Point,
pub max: Point,
}
impl PartialEq for Rectangle {
fn eq(&self, other: &Rectangle) -> bool {
(self.min == other.min && self.max == other.max) || self.empty() && other.empty()
}
}
impl Rectangle {
pub const fn new(min: Point, max: Point) -> Self {
Self { min, max }
}
pub fn dx(&self) -> usize {
(self.max.x - self.min.x).try_into().unwrap()
}
pub fn dy(&self) -> usize {
(self.max.y - self.min.y).try_into().unwrap()
}
pub fn size(&self) -> Point {
Point {
x: self.max.x - self.min.x,
y: self.max.y - self.min.y,
}
}
pub fn add(&self, p: &Point) -> Rectangle {
Rectangle::new(
Point::new(self.min.x + p.x, self.min.y + p.y),
Point::new(self.max.x + p.x, self.max.y + p.y),
)
}
pub fn intersect(&self, s: &Rectangle) -> Rectangle {
let r = Rectangle::new(
Point::new(self.min.x.max(s.min.x), self.min.y.max(s.min.y)),
Point::new(self.max.x.min(s.max.x), self.max.y.min(s.max.y)),
);
if r.empty() {
ZR
} else {
r
}
}
pub fn union(&self, s: &Rectangle) -> Rectangle {
if self.empty() {
return *s;
}
if s.empty() {
return *self;
}
Rectangle::new(
Point::new(self.min.x.min(s.min.x), self.min.y.min(s.min.y)),
Point::new(self.max.x.max(s.max.x), self.max.y.max(s.max.y)),
)
}
pub fn empty(&self) -> bool {
self.min.x >= self.max.x || self.min.y >= self.max.y
}
pub fn overlaps(&self, s: &Rectangle) -> bool {
!self.empty()
&& !s.empty()
&& self.min.x < s.max.x
&& s.min.x < self.max.x
&& self.min.y < s.max.y
&& s.min.y < self.max.y
}
pub fn inside(&self, s: &Rectangle) -> bool {
if self.empty() {
return true;
}
s.min.x <= self.min.x
&& self.max.x <= s.max.x
&& s.min.y <= self.min.y
&& self.max.y <= s.max.y
}
}
pub const ZR: Rectangle = Rectangle::new(Point::new(0, 0), Point::new(0, 0));
pub fn rect(x0: isize, y0: isize, x1: isize, y1: isize) -> Rectangle {
let mut x0 = x0;
let mut x1 = x1;
let mut y0 = y0;
let mut y1 = y1;
if x0 > x1 {
(x0, x1) = (x1, x0);
}
if y0 > y1 {
(y0, y1) = (y1, y0);
}
Rectangle {
min: Point { x: x0, y: y0 },
max: Point { x: x1, y: y1 },
}
}