2015-05-19 02:41:35 +00:00
|
|
|
//! Points on the 2D character grid.
|
2015-05-15 19:16:58 +00:00
|
|
|
|
2015-05-15 23:06:48 +00:00
|
|
|
use std::ops::{Add, Sub, Mul, Div};
|
2015-05-19 02:41:35 +00:00
|
|
|
use std::cmp::{min,max};
|
2015-05-15 18:58:47 +00:00
|
|
|
|
|
|
|
/// Simple 2D size, in characters.
|
|
|
|
#[derive(Clone,Copy)]
|
|
|
|
pub struct Vec2 {
|
|
|
|
/// X coordinate (column), from left to right.
|
2015-05-25 21:46:29 +00:00
|
|
|
pub x: usize,
|
2015-05-15 18:58:47 +00:00
|
|
|
/// Y coordinate (row), from top to bottom.
|
2015-05-25 21:46:29 +00:00
|
|
|
pub y: usize,
|
2015-05-15 18:58:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Vec2 {
|
|
|
|
/// Creates a new Vec2 from coordinates.
|
2015-05-25 21:46:29 +00:00
|
|
|
pub fn new(x: usize, y: usize) -> Self {
|
2015-05-15 18:58:47 +00:00
|
|
|
Vec2 {
|
|
|
|
x: x,
|
|
|
|
y: y,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-19 02:41:35 +00:00
|
|
|
/// Returns a new Vec2 that is a maximum per coordinate.
|
|
|
|
pub fn max(a: Self, b: Self) -> Self {
|
|
|
|
Vec2::new(max(a.x, b.x), max(a.y, b.y))
|
|
|
|
}
|
|
|
|
|
2015-05-15 18:58:47 +00:00
|
|
|
/// Returns a new Vec2 that is no larger than any input in both dimensions.
|
2015-05-19 02:41:35 +00:00
|
|
|
pub fn min(a: Self, b: Self) -> Self {
|
|
|
|
Vec2::new(min(a.x, b.x), min(a.y, b.y))
|
|
|
|
}
|
|
|
|
|
2015-05-20 18:11:55 +00:00
|
|
|
/// Returns a vector with the X component of self, and y=0.
|
2015-05-19 02:41:35 +00:00
|
|
|
pub fn keep_x(&self) -> Self {
|
|
|
|
Vec2::new(self.x, 0)
|
|
|
|
}
|
|
|
|
|
2015-05-20 18:11:55 +00:00
|
|
|
/// Returns a vector with the Y component of self, and x=0.
|
2015-05-19 02:41:35 +00:00
|
|
|
pub fn keep_y(&self) -> Self {
|
|
|
|
Vec2::new(0, self.y)
|
|
|
|
}
|
|
|
|
|
2015-05-20 18:11:55 +00:00
|
|
|
/// Alias for Vec::new(0,0).
|
2015-05-19 02:41:35 +00:00
|
|
|
pub fn zero() -> Self {
|
|
|
|
Vec2::new(0,0)
|
2015-05-15 18:58:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A generic trait for converting a value into a 2D vector.
|
|
|
|
pub trait ToVec2 {
|
2015-05-20 18:11:55 +00:00
|
|
|
/// Converts self into a Vec2.
|
2015-05-15 18:58:47 +00:00
|
|
|
fn to_vec2(self) -> Vec2;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToVec2 for Vec2 {
|
|
|
|
fn to_vec2(self) -> Vec2 {
|
|
|
|
self
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-20 17:31:38 +00:00
|
|
|
impl ToVec2 for (i32,i32) {
|
|
|
|
fn to_vec2(self) -> Vec2 {
|
2015-05-25 21:46:29 +00:00
|
|
|
(self.0 as usize, self.1 as usize).to_vec2()
|
2015-05-20 17:31:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-25 21:46:29 +00:00
|
|
|
impl ToVec2 for (usize,usize) {
|
2015-05-15 18:58:47 +00:00
|
|
|
fn to_vec2(self) -> Vec2 {
|
|
|
|
Vec2::new(self.0, self.1)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-25 21:46:29 +00:00
|
|
|
impl ToVec2 for (u32,u32) {
|
2015-05-15 22:00:20 +00:00
|
|
|
fn to_vec2(self) -> Vec2 {
|
2015-05-25 21:46:29 +00:00
|
|
|
Vec2::new(self.0 as usize, self.1 as usize)
|
2015-05-15 22:00:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-16 21:02:15 +00:00
|
|
|
impl <T: ToVec2> Add<T> for Vec2 {
|
2015-05-15 18:58:47 +00:00
|
|
|
type Output = Vec2;
|
|
|
|
|
2015-05-16 21:02:15 +00:00
|
|
|
fn add(self, other: T) -> Vec2 {
|
|
|
|
let ov = other.to_vec2();
|
2015-05-15 18:58:47 +00:00
|
|
|
Vec2 {
|
2015-05-16 21:02:15 +00:00
|
|
|
x: self.x + ov.x,
|
|
|
|
y: self.y + ov.y,
|
2015-05-15 18:58:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-16 21:02:15 +00:00
|
|
|
impl <T: ToVec2> Sub<T> for Vec2 {
|
2015-05-15 18:58:47 +00:00
|
|
|
type Output = Vec2;
|
|
|
|
|
2015-05-16 21:02:15 +00:00
|
|
|
fn sub(self, other: T) -> Vec2 {
|
|
|
|
let ov = other.to_vec2();
|
2015-05-15 18:58:47 +00:00
|
|
|
Vec2 {
|
2015-05-16 21:02:15 +00:00
|
|
|
x: self.x - ov.x,
|
|
|
|
y: self.y - ov.y,
|
2015-05-15 18:58:47 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-05-15 23:06:48 +00:00
|
|
|
|
2015-05-25 21:46:29 +00:00
|
|
|
impl Div<usize> for Vec2 {
|
2015-05-15 23:06:48 +00:00
|
|
|
type Output = Vec2;
|
|
|
|
|
2015-05-25 21:46:29 +00:00
|
|
|
fn div(self, other: usize) -> Vec2 {
|
2015-05-15 23:06:48 +00:00
|
|
|
Vec2 {
|
|
|
|
x: self.x / other,
|
|
|
|
y: self.y / other,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-25 21:46:29 +00:00
|
|
|
impl Mul<usize> for Vec2 {
|
2015-05-15 23:06:48 +00:00
|
|
|
type Output = Vec2;
|
|
|
|
|
2015-05-25 21:46:29 +00:00
|
|
|
fn mul(self, other: usize) -> Vec2 {
|
2015-05-15 23:06:48 +00:00
|
|
|
Vec2 {
|
|
|
|
x: self.x * other,
|
|
|
|
y: self.y * other,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-05-25 21:56:51 +00:00
|
|
|
|
|
|
|
/// Four values representing each direction.
|
|
|
|
pub struct Vec4 {
|
|
|
|
/// Left margin
|
|
|
|
pub left: usize,
|
|
|
|
/// Right margin
|
|
|
|
pub right: usize,
|
|
|
|
/// Top margin
|
|
|
|
pub top: usize,
|
|
|
|
/// Bottom margin
|
|
|
|
pub bottom: usize,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Vec4 {
|
|
|
|
/// Creates a new Vec4.
|
|
|
|
pub fn new(left: usize, right: usize, top: usize, bottom: usize) -> Self {
|
|
|
|
Vec4 {
|
|
|
|
left: left,
|
|
|
|
right: right,
|
|
|
|
top: top,
|
|
|
|
bottom: bottom,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns left + right.
|
|
|
|
pub fn horizontal(&self) -> usize {
|
|
|
|
self.left + self.right
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns top + bottom.
|
|
|
|
pub fn vertical(&self) -> usize {
|
|
|
|
self.top + self.bottom
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns (left+right, top+bottom).
|
|
|
|
pub fn combined(&self) -> Vec2 {
|
|
|
|
Vec2::new(self.horizontal(), self.vertical())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns (left, top).
|
|
|
|
pub fn top_left(&self) -> Vec2 {
|
|
|
|
Vec2::new(self.left, self.top)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns (right, bottom).
|
|
|
|
pub fn bot_right(&self) -> Vec2 {
|
|
|
|
Vec2::new(self.right, self.bottom)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Generic trait for converting a value into a Vec4.
|
|
|
|
pub trait ToVec4 {
|
|
|
|
/// Converts self to a Vec4.
|
|
|
|
fn to_vec4(self) -> Vec4;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToVec4 for Vec4 {
|
|
|
|
fn to_vec4(self) -> Vec4 { self }
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToVec4 for (usize,usize,usize,usize) {
|
|
|
|
fn to_vec4(self) -> Vec4 {
|
|
|
|
Vec4::new(self.0, self.1, self.2, self.3)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ToVec4 for (i32,i32,i32,i32) {
|
|
|
|
fn to_vec4(self) -> Vec4 {
|
|
|
|
Vec4::new(self.0 as usize, self.1 as usize, self.2 as usize, self.3 as usize)
|
|
|
|
}
|
|
|
|
}
|