use glam::IVec2;
use crate::point::GridPoint;
pub const UP: IVec2 = IVec2::from_array([0, 1]);
pub const DOWN: IVec2 = IVec2::from_array([0, -1]);
pub const LEFT: IVec2 = IVec2::from_array([-1, 0]);
pub const RIGHT: IVec2 = IVec2::from_array([1, 0]);
pub const UP_LEFT: IVec2 = IVec2::from_array([-1, 1]);
pub const UP_RIGHT: IVec2 = IVec2::from_array([1, 1]);
pub const DOWN_LEFT: IVec2 = IVec2::from_array([-1, -1]);
pub const DOWN_RIGHT: IVec2 = IVec2::from_array([1, -1]);
pub const DIR_4: &[IVec2] = &[UP, DOWN, LEFT, RIGHT];
pub const DIR_8: &[IVec2] = &[
UP, DOWN, LEFT, RIGHT, UP_LEFT, UP_RIGHT, DOWN_LEFT, DOWN_RIGHT,
];
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Dir4 {
Up,
Down,
Left,
Right,
}
impl From<Dir4> for IVec2 {
fn from(d: Dir4) -> Self {
match d {
Dir4::Up => UP,
Dir4::Down => DOWN,
Dir4::Left => LEFT,
Dir4::Right => RIGHT,
}
}
}
impl Dir4 {
pub fn from_point(p: impl GridPoint) -> Option<Dir4> {
match p.as_ivec2().signum().to_array() {
[0, 1] => Some(Dir4::Up),
[0, -1] => Some(Dir4::Down),
[-1, 0] => Some(Dir4::Left),
[1, 0] => Some(Dir4::Right),
_ => None,
}
}
pub fn from_index(i: usize) -> Option<Dir4> {
match i {
0 => Some(Dir4::Up),
1 => Some(Dir4::Down),
2 => Some(Dir4::Left),
3 => Some(Dir4::Right),
_ => None,
}
}
pub fn to_index(&self) -> usize {
match self {
Dir4::Up => 0,
Dir4::Down => 1,
Dir4::Left => 2,
Dir4::Right => 3,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Dir8 {
Up,
Down,
Left,
Right,
UpLeft,
UpRight,
DownLeft,
DownRight,
}
impl Dir8 {
pub fn from_point(p: impl GridPoint) -> Option<Dir8> {
match p.as_ivec2().signum().to_array() {
[0, 1] => Some(Dir8::Up),
[0, -1] => Some(Dir8::Down),
[-1, 0] => Some(Dir8::Left),
[1, 0] => Some(Dir8::Right),
[-1, 1] => Some(Dir8::UpLeft),
[1, 1] => Some(Dir8::UpRight),
[-1, -1] => Some(Dir8::DownLeft),
[1, -1] => Some(Dir8::DownRight),
_ => None,
}
}
pub fn from_index(i: usize) -> Option<Dir8> {
match i {
0 => Some(Dir8::Up),
1 => Some(Dir8::Down),
2 => Some(Dir8::Left),
3 => Some(Dir8::Right),
4 => Some(Dir8::UpLeft),
5 => Some(Dir8::UpRight),
6 => Some(Dir8::DownLeft),
7 => Some(Dir8::DownRight),
_ => None,
}
}
pub fn to_index(&self) -> usize {
match self {
Dir8::Up => 0,
Dir8::Down => 1,
Dir8::Left => 2,
Dir8::Right => 3,
Dir8::UpLeft => 4,
Dir8::UpRight => 5,
Dir8::DownLeft => 6,
Dir8::DownRight => 7,
}
}
}
impl From<Dir8> for IVec2 {
fn from(d: Dir8) -> Self {
match d {
Dir8::Up => UP,
Dir8::Down => DOWN,
Dir8::Left => LEFT,
Dir8::Right => RIGHT,
Dir8::UpLeft => UP_LEFT,
Dir8::UpRight => UP_RIGHT,
Dir8::DownLeft => DOWN_LEFT,
Dir8::DownRight => DOWN_RIGHT,
}
}
}