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 7c79938212 - Show all commits

View file

@ -1,8 +1,8 @@
//! All functions related to calculations in a hexagonal grid. //! All functions related to calculations in a hexagonal grid.
use std::ops::{ use std::{collections::HashSet, ops::{
Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign, Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, RemAssign, Sub, SubAssign,
}; }};
use paste::paste; use paste::paste;
@ -59,6 +59,12 @@ pub trait Number:
/// Converts an `usize` to `Self`. /// Converts an `usize` to `Self`.
fn from_usize(value: usize) -> Self; fn from_usize(value: usize) -> Self;
/// Converts `self` to an `f32`.
fn to_f32(self) -> f32;
/// Converts an `f32` to `Self`.
fn from_f32(value: f32) -> Self;
} }
/// Implements the `Number` trait for the given types. /// Implements the `Number` trait for the given types.
@ -79,6 +85,14 @@ macro_rules! number_impl {
value as $t value as $t
} }
fn to_f32(self) -> f32 {
self as f32
}
fn from_f32(value: f32) -> Self {
value as $t
}
} }
)*}}; )*}};
@ -220,12 +234,33 @@ impl<T: Number> HexPosition<T> {
Self(x, y) Self(x, y)
} }
/// Returns the pixel coordinates of the hexagonal position.
pub fn to_pixel_coordinates(&self, size: (f32, f32)) -> (f32, f32) {
(
size.0
* 3f32
.sqrt()
.mul_add(T::to_f32(self.0), 3f32.sqrt() / 2.0 * T::to_f32(self.0)),
size.1 * (3.0 / 2.0 * T::to_f32(self.1)),
)
}
/// Returns the distance between two hexagonal positions. /// Returns the distance between two hexagonal positions.
pub fn distance(self, other: Self) -> T { pub fn distance(self, other: Self) -> T {
let Self(x, y) = self - other; let Self(x, y) = self - other;
x.abs() + y.abs() + (x + y).abs() / T::TWO x.abs() + y.abs() + (x + y).abs() / T::TWO
} }
pub fn range(&self, range: T) -> HashSet<Self> {
let mut result_positions = HashSet::new();
for q in num::range_inclusive(-range, range) {
for r in num::range_inclusive((-range, -q - range), min(range, -q + range)) {
result_positions.insert(Self { q, r });
}
}
result_positions
}
/// Returns the hexagonal ring of the given radius. /// Returns the hexagonal ring of the given radius.
pub fn ring(self, radius: usize) -> HexRing<T> { pub fn ring(self, radius: usize) -> HexRing<T> {
HexRing { HexRing {