//! Some generic geometry routines used in atlas packing. use std::ops::{Add, Sub, Mul}; use std::convert::From; use num_traits::cast::NumCast; use rusttype; /// A rectangle. #[derive(Debug, Hash, Eq, PartialEq, Copy, Clone)] pub struct Rect { pub x: T, pub y: T, pub w: T, pub h: T, } #[allow(dead_code)] impl Rect where T: Copy + Add + Sub + Mul + PartialOrd { /// Returns a new rectangle given the upper-left corner and its width + height. pub fn new(x: T, y: T, w: T, h: T) -> Rect { Rect { x: x, y: y, w: w, h: h, } } /// Returns a new rectangle given a pair of points in opposing corners. pub fn from_points(x1: T, y1: T, x2: T, y2: T) -> Rect { Rect { x: x1, y: y1, w: x2 - x1, h: y2 - y1 } } /// Return the position of the top edge of the rectangle. #[inline(always)] pub fn top(&self) -> T {self.y} /// Return the position of the left edge of the rectangle. #[inline(always)] pub fn left(&self) -> T {self.x} /// Return the position of the bottom edge of the rectangle (coord system with 0 at top). #[inline(always)] pub fn bottom(&self) -> T {self.y + self.h} /// Return the position of the bottom edge of the rectangle (gl/mathematical coord system). #[inline(always)] pub fn gl_bottom(&self) -> T {self.y - self.h} /// Return the position of the right edge of the rectangle. #[inline(always)] pub fn right(&self) -> T {self.x + self.w} /// Return the area of the rectangle. #[inline(always)] pub fn area(&self) -> T {self.x * self.y} /// Given this rectangle and another rectangle, return true if they intersect. pub fn intersects(&self, other: &Rect) -> bool { self.left() < other.right() && self.right() > other.left() && self.top() < other.bottom() && self.bottom() > other.top() } /// Return true if this rectangle completely contains another rectangle. pub fn contains(&self, other: &Rect) -> bool { self.left() <= other.left() && self.right() >= other.right() && self.top() <= other.top() && self.bottom() >= other.bottom() } } impl From> for Rect where T: Sub + Copy { fn from(rect: rusttype::Rect) -> Self { Rect { x: rect.min.x, y: rect.min.y, w: rect.width(), h: rect.height(), } } } /// A 2D vector #[derive(Debug, Hash, Eq, PartialEq, Copy, Clone)] pub struct Vec2 { pub x: T, pub y: T } impl Vec2 { pub fn new(x: T, y: T) -> Vec2 { Vec2 { x: x, y: y, } } } impl From<(T, T)> for Vec2 { fn from(tuple: (T, T)) -> Self { Vec2 { x: tuple.0, y: tuple.1, } } } impl Vec2 where S: NumCast + Copy { pub fn cast(&self) -> Vec2 where T: NumCast { Vec2 { x: NumCast::from(self.x).unwrap(), y: NumCast::from(self.y).unwrap(), } } }