70 lines
1.7 KiB
Rust
70 lines
1.7 KiB
Rust
use std::ops::Add;
|
|
use num_integer::Roots;
|
|
use crate::system::{GriddedPosition, Position};
|
|
use serde::{Serialize, Deserialize};
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub struct HexPosition {
|
|
pub q: i32,
|
|
pub r: i32,
|
|
}
|
|
|
|
impl Add for HexPosition {
|
|
type Output = Self;
|
|
|
|
fn add(self, rhs: Self) -> Self::Output {
|
|
HexPosition { q: self.q + rhs.q, r: self.r + rhs.r }
|
|
}
|
|
}
|
|
|
|
impl GriddedPosition for HexPosition {
|
|
const NEIGHBOURS: u32 = 6;
|
|
|
|
fn neighbour(&self, neighbour_index: u32) -> Self {
|
|
let neighbour_index = neighbour_index as usize;
|
|
|
|
const OFFSETS: [(i32, i32); 6] = [
|
|
(1, 0), (1, -1), (0, -1),
|
|
(-1, 0), (-1, 1), (0, 1),
|
|
];
|
|
|
|
self.clone() + HexPosition { q: OFFSETS[neighbour_index].0, r: OFFSETS[neighbour_index].1 }
|
|
}
|
|
|
|
fn linear_index(&self, grid_size: u32) -> usize {
|
|
let q = (self.q + (grid_size as i32 / 2)) as usize;
|
|
let r = (self.r + (grid_size as i32 / 2)) as usize;
|
|
|
|
r * (grid_size as usize) + q
|
|
}
|
|
}
|
|
|
|
impl Position for HexPosition {
|
|
// const DIM: usize = 2;
|
|
type Cartesian = [f32; 2];
|
|
|
|
fn zero() -> Self {
|
|
HexPosition { q: 0, r: 0 }
|
|
}
|
|
|
|
fn abs(&self) -> f32 {
|
|
((self.q.pow(2) + self.r.pow(2) + self.q * self.r) as f32).sqrt()
|
|
}
|
|
|
|
fn from_cartesian(cartesian: Self::Cartesian) -> Self {
|
|
let q = (1.0f32 / 3.0f32).sqrt() * cartesian[0] - 1.0 / 3.0 * cartesian[1];
|
|
let r = 2.0 / 3.0 * cartesian[1];
|
|
|
|
Self { q: q as i32, r: r as i32 }
|
|
}
|
|
|
|
fn to_cartesian(&self) -> Self::Cartesian {
|
|
let q = self.q as f32;
|
|
let r = self.r as f32;
|
|
[
|
|
3f32.sqrt() * q + 3f32.sqrt() / 2f32 * r,
|
|
(3. / 2.) * r
|
|
]
|
|
}
|
|
}
|