Add Rect
This commit is contained in:
parent
52c5778a19
commit
4bf7a0c9b2
3 changed files with 169 additions and 7 deletions
|
|
@ -1,4 +1,5 @@
|
|||
pub use crate::{buffer::Buffer, vec2::Vec2};
|
||||
pub use crate::{buffer::Buffer, rect::Rect, vec2::Vec2};
|
||||
|
||||
mod buffer;
|
||||
mod rect;
|
||||
mod vec2;
|
||||
|
|
|
|||
118
showbits-common/src/rect.rs
Normal file
118
showbits-common/src/rect.rs
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
use std::ops::{Add, Sub};
|
||||
|
||||
use crate::Vec2;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub struct Rect {
|
||||
north: i32,
|
||||
south: i32,
|
||||
west: i32,
|
||||
east: i32,
|
||||
}
|
||||
|
||||
impl Rect {
|
||||
/// Whenever a `Rect` is constructed, this function must be used. This
|
||||
/// ensures invariants are always checked.
|
||||
fn new(north: i32, south: i32, west: i32, east: i32) -> Self {
|
||||
let result = Self {
|
||||
north,
|
||||
south,
|
||||
west,
|
||||
east,
|
||||
};
|
||||
|
||||
let size = result.size();
|
||||
assert!(size.x >= 0);
|
||||
assert!(size.y >= 0);
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Construct a `Rect` that is a bounding box around two points.
|
||||
///
|
||||
/// It is not possible to construct a `Rect` with a width or height of 0
|
||||
/// through this method. Use one of the other constructor functions instead.
|
||||
pub fn from_points(a: Vec2, b: Vec2) -> Self {
|
||||
Self::new(a.y.min(b.y), a.y.max(b.y), a.x.min(b.x), a.x.max(b.x))
|
||||
}
|
||||
|
||||
/// Construct a `Rect` from its north-west and south-east corners.
|
||||
pub fn from_nw_se(nw: Vec2, se: Vec2) -> Self {
|
||||
Self::new(nw.y, se.y, nw.x, se.x)
|
||||
}
|
||||
|
||||
/// Construct a `Rect` from its north-east and south-west corners.
|
||||
pub fn from_ne_sw(ne: Vec2, sw: Vec2) -> Self {
|
||||
Self::new(ne.y, sw.y, sw.x, ne.x)
|
||||
}
|
||||
|
||||
/// Construct a `Rect` from its north-west corner and size.
|
||||
pub fn from_nw(nw: Vec2, size: Vec2) -> Self {
|
||||
let se = nw + (size - 1);
|
||||
Self::from_nw_se(nw, se)
|
||||
}
|
||||
|
||||
/// Construct a `Rect` from its north-east corner and size.
|
||||
pub fn from_corner_ne(ne: Vec2, size: Vec2) -> Self {
|
||||
let sw = ne + (size - 1).neg_x();
|
||||
Self::from_ne_sw(ne, sw)
|
||||
}
|
||||
|
||||
/// Construct a `Rect` from its south-west corner and size.
|
||||
pub fn from_corner_sw(sw: Vec2, size: Vec2) -> Self {
|
||||
let ne = sw + (size - 1).neg_y();
|
||||
Self::from_ne_sw(ne, sw)
|
||||
}
|
||||
|
||||
/// Construct a `Rect` from its south-east corner and size.
|
||||
pub fn from_corner_se(se: Vec2, size: Vec2) -> Self {
|
||||
let nw = se - (size - 1);
|
||||
Self::from_nw_se(nw, se)
|
||||
}
|
||||
|
||||
pub fn corner_nw(&self) -> Vec2 {
|
||||
Vec2::new(self.west, self.north)
|
||||
}
|
||||
|
||||
pub fn corner_ne(&self) -> Vec2 {
|
||||
Vec2::new(self.east, self.north)
|
||||
}
|
||||
|
||||
pub fn corner_sw(&self) -> Vec2 {
|
||||
Vec2::new(self.west, self.south)
|
||||
}
|
||||
|
||||
pub fn corner_se(&self) -> Vec2 {
|
||||
Vec2::new(self.east, self.south)
|
||||
}
|
||||
|
||||
pub fn size(&self) -> Vec2 {
|
||||
Vec2::new(self.east - self.west + 1, self.south - self.north + 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<Vec2> for Rect {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Vec2) -> Self::Output {
|
||||
Self::new(
|
||||
self.north + rhs.y,
|
||||
self.south + rhs.y,
|
||||
self.west + rhs.x,
|
||||
self.east + rhs.x,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<Vec2> for Rect {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, rhs: Vec2) -> Self::Output {
|
||||
Self::new(
|
||||
self.north - rhs.y,
|
||||
self.south - rhs.y,
|
||||
self.west - rhs.x,
|
||||
self.east - rhs.x,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -20,9 +20,39 @@ impl Vec2 {
|
|||
Self { x, y }
|
||||
}
|
||||
|
||||
/// The vector pointing from `self` to `other`.
|
||||
///
|
||||
/// ```
|
||||
/// # use showbits_common::Vec2;
|
||||
/// let a = Vec2::new(1, 3);
|
||||
/// let b = Vec2::new(3, 7);
|
||||
/// assert_eq!(a.to(b), b - a);
|
||||
/// ```
|
||||
pub fn to(self, other: Self) -> Self {
|
||||
other - self
|
||||
}
|
||||
|
||||
/// Negate the `x` component of the vector.
|
||||
///
|
||||
/// ```
|
||||
/// # use showbits_common::Vec2;
|
||||
/// let v = Vec2::new(3, 4);
|
||||
/// assert_eq!(v.neg_x(), v * Vec2::new(-1, 1));
|
||||
/// ```
|
||||
pub fn neg_x(self) -> Self {
|
||||
Self { x: -self.x, ..self }
|
||||
}
|
||||
|
||||
/// Negate the `y` component of the vector.
|
||||
///
|
||||
/// ```
|
||||
/// # use showbits_common::Vec2;
|
||||
/// let v = Vec2::new(3, 4);
|
||||
/// assert_eq!(v.neg_y(), v * Vec2::new(1, -1));
|
||||
/// ```
|
||||
pub fn neg_y(self) -> Self {
|
||||
Self { y: -self.y, ..self }
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Vec2 {
|
||||
|
|
@ -53,6 +83,14 @@ impl Add for Vec2 {
|
|||
}
|
||||
}
|
||||
|
||||
impl Add<i32> for Vec2 {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: i32) -> Self::Output {
|
||||
self + Self::new(rhs, rhs)
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub for Vec2 {
|
||||
type Output = Self;
|
||||
|
||||
|
|
@ -64,14 +102,11 @@ impl Sub for Vec2 {
|
|||
}
|
||||
}
|
||||
|
||||
impl Mul<i32> for Vec2 {
|
||||
impl Sub<i32> for Vec2 {
|
||||
type Output = Self;
|
||||
|
||||
fn mul(self, rhs: i32) -> Self::Output {
|
||||
Self {
|
||||
x: self.x * rhs,
|
||||
y: self.y * rhs,
|
||||
}
|
||||
fn sub(self, rhs: i32) -> Self::Output {
|
||||
self - Self::new(rhs, rhs)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -85,3 +120,11 @@ impl Mul for Vec2 {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<i32> for Vec2 {
|
||||
type Output = Self;
|
||||
|
||||
fn mul(self, rhs: i32) -> Self::Output {
|
||||
self * Self::new(rhs, rhs)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue