cdungeon/src/geometry.rs
Paul Brinkmeier 966582e0c2 Add dash
2025-11-30 02:38:35 +01:00

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
}
}
}