107 lines
2.4 KiB
Rust
107 lines
2.4 KiB
Rust
use std::ops::{Add, Div, Sub};
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq)]
|
|
pub struct P2<T> {
|
|
pub x: T,
|
|
pub y: T,
|
|
}
|
|
|
|
impl<T> P2<T> {
|
|
pub fn new(x: T, y: T) -> Self {
|
|
Self { x, y }
|
|
}
|
|
}
|
|
|
|
impl<T: Copy + Add<T>> Add<V2<T>> for P2<T> {
|
|
type Output = P2<<T as Add>::Output>;
|
|
|
|
fn add(self, rhs: V2<T>) -> Self::Output {
|
|
P2::new(self.x + rhs.x, self.y + rhs.y)
|
|
}
|
|
}
|
|
|
|
impl<T: Copy + Sub<T>> Sub<P2<T>> for P2<T> {
|
|
type Output = V2<<T as Sub>::Output>;
|
|
|
|
fn sub(self, rhs: P2<T>) -> Self::Output {
|
|
V2::new(self.x - rhs.x, self.y - rhs.y)
|
|
}
|
|
}
|
|
|
|
impl<T: Copy + Sub<T>> Sub<V2<T>> for P2<T> {
|
|
type Output = P2<<T as Sub>::Output>;
|
|
|
|
fn sub(self, rhs: V2<T>) -> Self::Output {
|
|
P2::new(self.x - rhs.x, self.y - rhs.y)
|
|
}
|
|
}
|
|
|
|
impl<T: Copy + Div<T>> Div<T> for P2<T> {
|
|
type Output = P2<<T as Div>::Output>;
|
|
|
|
fn div(self, rhs: T) -> Self::Output {
|
|
P2::new(self.x / rhs, self.y / rhs)
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug)]
|
|
pub struct V2<T> {
|
|
pub x: T,
|
|
pub y: T,
|
|
}
|
|
|
|
impl<T> V2<T> {
|
|
pub fn new(x: T, y: T) -> Self {
|
|
Self { x, y }
|
|
}
|
|
}
|
|
|
|
impl<T: Copy + Div<T>> Div<T> for V2<T> {
|
|
type Output = V2<<T as Div>::Output>;
|
|
|
|
fn div(self, rhs: T) -> Self::Output {
|
|
V2::new(self.x / rhs, self.y / rhs)
|
|
}
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct Grid<T> {
|
|
pub dims: V2<usize>,
|
|
elements: Vec<T>,
|
|
}
|
|
|
|
impl<T> Grid<T> {
|
|
pub fn from_fn(width: usize, height: usize, mut f: impl FnMut(usize, usize) -> T) -> Self {
|
|
let mut elements = Vec::new();
|
|
for y in 0..height {
|
|
for x in 0..width {
|
|
elements.push(f(x, y));
|
|
}
|
|
}
|
|
Self {
|
|
dims: V2::new(width, height),
|
|
elements,
|
|
}
|
|
}
|
|
|
|
pub fn get(&self, index: P2<isize>) -> Option<&T> {
|
|
self.valid_index(index).map(|index| &self.elements[index])
|
|
}
|
|
|
|
pub fn get_mut(&mut self, index: P2<isize>) -> Option<&mut T> {
|
|
self.valid_index(index)
|
|
.map(|index| &mut self.elements[index])
|
|
}
|
|
|
|
fn valid_index(&self, index: P2<isize>) -> Option<usize> {
|
|
if index.x >= 0
|
|
&& (index.x as usize) < self.dims.x
|
|
&& index.y >= 0
|
|
&& (index.y as usize) < self.dims.y
|
|
{
|
|
Some((index.y as usize) * self.dims.x + (index.x as usize))
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
} |