123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- use std::cmp::{max, min};
- #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
- pub struct Size {
- pub width: usize,
- pub height: usize,
- }
- impl specs::Component for Size {
- type Storage = specs::VecStorage<Self>;
- }
- impl From<[usize; 2]> for Size {
- fn from([width, height]: [usize; 2]) -> Size {
- Size { width, height }
- }
- }
- #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
- pub struct Coord {
- pub x: usize,
- pub y: usize,
- }
- impl Coord {
- pub fn new(x: usize, y: usize) -> Coord {
- Coord { x, y }
- }
- }
- impl specs::Component for Coord {
- type Storage = specs::VecStorage<Coord>;
- }
- impl From<[usize; 2]> for Coord {
- fn from([x, y]: [usize; 2]) -> Coord {
- Coord { x, y }
- }
- }
- impl std::ops::Add for Coord {
- type Output = Self;
- fn add(self, other: Self) -> Self {
- Coord {
- x: self.x + other.x,
- y: self.y + other.y,
- }
- }
- }
- impl std::ops::Add<usize> for Coord {
- type Output = Self;
- fn add(self, other: usize) -> Self {
- Coord {
- x: self.x + other,
- y: self.y + other,
- }
- }
- }
- impl std::ops::Add<isize> for Coord {
- type Output = Self;
- fn add(self, other: isize) -> Self {
- Coord {
- x: (self.x as isize + other) as usize,
- y: (self.y as isize + other) as usize,
- }
- }
- }
- impl std::ops::Add<(isize, isize)> for Coord {
- type Output = Self;
- fn add(self, other: (isize, isize)) -> Self {
- Coord {
- x: (self.x as isize + other.0) as usize,
- y: (self.y as isize + other.1) as usize,
- }
- }
- }
- impl std::ops::Sub for Coord {
- type Output = Self;
- fn sub(self, other: Self) -> Self {
- Coord {
- x: self.x - other.x,
- y: self.y - other.y,
- }
- }
- }
- impl std::ops::Sub<usize> for Coord {
- type Output = Self;
- fn sub(self, other: usize) -> Self {
- Coord {
- x: self.x - other,
- y: self.y - other,
- }
- }
- }
- #[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
- pub struct Rect {
- pub origin: Coord,
- pub size: Size,
- }
- impl Rect {
- pub fn new(origin: impl Into<Coord>, size: impl Into<Size>) -> Rect {
- let origin = origin.into();
- let size = size.into();
- Rect { origin, size }
- }
- pub fn from_points(p1: impl Into<Coord>, p2: impl Into<Coord>) -> Rect {
- let p1 = p1.into();
- let p2 = p2.into();
- let origin = Coord {
- x: min(p1.x, p2.x),
- y: min(p1.y, p2.y),
- };
- let size = Size {
- width: max(max(p1.x, p2.x) - origin.x, 1),
- height: max(max(p1.y, p2.y) - origin.y, 1),
- };
- Rect { origin, size }
- }
- pub fn area(&self) -> usize {
- self.size.width * self.size.height
- }
- pub fn width(&self) -> usize {
- self.size.width
- }
- pub fn height(&self) -> usize {
- self.size.height
- }
- pub fn x(&self) -> usize {
- self.origin.x
- }
- pub fn y(&self) -> usize {
- self.origin.y
- }
- pub fn contains(&self, pt: impl Into<Coord>) -> bool {
- let pt = pt.into();
- pt.x >= self.origin.x
- && pt.y >= self.origin.y
- && pt.x < self.origin.x + self.size.width
- && pt.y < self.origin.y + self.size.height
- }
- pub fn overlaps(&self, other: Rect) -> bool {
- if self.x() > other.x() + other.width() || other.x() > self.x() + self.width() {
- return false;
- }
- if self.y() > other.y() + other.height() || other.y() > self.y() + self.height() {
- return false;
- }
- true
- }
- pub fn center(&self) -> Coord {
- Coord {
- x: self.x() + (self.width() / 2),
- y: self.y() + (self.height() / 2),
- }
- }
- }
|