Remake utils for hexagon grids #55

Merged
CoCo_Sol merged 10 commits from remake-utile into main 2024-02-16 21:17:15 +00:00
Showing only changes of commit 6fb4996b8c - Show all commits

View file

@ -4,8 +4,6 @@ use std::ops::{
Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign,
};
use num::cast::AsPrimitive;
use num::FromPrimitive;
use paste::paste;
/// Represents a number that can be used in calculations for hexagonal grids.
@ -59,9 +57,11 @@ pub trait Number:
/// Converts `self` to an `usize`.
fn to_usize(self) -> usize;
/// Converts an `usize` to `Self`.
fn from_usize(value: usize) -> Self;
}
/// Implements the `Number` trait for the given types.
macro_rules! number_impl {
($($t:ty,)*) => {paste!{$(
impl Number for $t {
@ -117,23 +117,30 @@ pub enum HexDirection {
impl HexDirection {
/// Returns the vector of the direction.
pub fn to_vector<T: Number>(self) -> HexPosition<T> {
pub const fn to_vector<T: Number>(self) -> HexPosition<T> {
match self {
HexDirection::Right => HexPosition(T::ONE, T::ZERO),
HexDirection::UpRight => HexPosition(T::ONE, T::MINUS_ONE),
HexDirection::UpLeft => HexPosition(T::ZERO, T::MINUS_ONE),
HexDirection::Left => HexPosition(T::MINUS_ONE, T::ZERO),
HexDirection::DownLeft => HexPosition(T::MINUS_ONE, T::ONE),
HexDirection::DownRight => HexPosition(T::ZERO, T::ONE),
Self::Right => HexPosition(T::ONE, T::ZERO),
Self::UpRight => HexPosition(T::ONE, T::MINUS_ONE),
Self::UpLeft => HexPosition(T::ZERO, T::MINUS_ONE),
Self::Left => HexPosition(T::MINUS_ONE, T::ZERO),
Self::DownLeft => HexPosition(T::MINUS_ONE, T::ONE),
Self::DownRight => HexPosition(T::ZERO, T::ONE),
}
}
}
/// A hexagonal ring iterator.
pub struct HexRing<T: Number> {
/// The current position in the ring.
current: HexPosition<T>,
/// The direction of the current position to the next in the ring.
direction: HexDirection,
/// The radius of the ring.
radius: usize,
/// The index of the current position in the ring.
index: usize,
}
@ -173,9 +180,16 @@ impl<T: Number> Iterator for HexRing<T> {
/// A hexagonal spiral iterator.
pub struct HexSpiral<T: Number> {
/// The origin of the spiral.
origin: HexPosition<T>,
/// The current ring of the spiral.
current: HexRing<T>,
/// The radius of the spiral.
radius: usize,
/// The index of the current ring in the spiral.
index: usize,
}
@ -202,7 +216,7 @@ impl<T: Number> Iterator for HexSpiral<T> {
impl<T: Number> HexPosition<T> {
/// Creates a new hexagonal position.
pub fn new(x: T, y: T) -> Self {
pub const fn new(x: T, y: T) -> Self {
Self(x, y)
}
@ -215,7 +229,7 @@ impl<T: Number> HexPosition<T> {
/// Returns the hexagonal ring of the given radius.
pub fn ring(self, radius: usize) -> HexRing<T> {
HexRing {
current: self + HexDirection::DownLeft.to_vector() * radius.from_usize(),
current: self + HexDirection::DownLeft.to_vector() * T::from_usize(radius),
direction: HexDirection::Right,
radius,
index: 0,
@ -233,6 +247,7 @@ impl<T: Number> HexPosition<T> {
}
}
/// Implementation of the arithmetic operators for hexagonal positions.
macro_rules! impl_ops {
($(($t:ty, $n:ident),)*) => {paste!{$(
impl<T: Number> $t for HexPosition<T> {