generated from tipragot/rust
Add utils for hexagonal grild #50
|
@ -1,28 +1,10 @@
|
||||||
//! This file contains utilities for working with hex coordinates.
|
//! All fonction related to calculations in hexagonal grid.
|
||||||
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::ops;
|
use std::ops;
|
||||||
|
|
||||||
/// Contains all "HexPosition" neighbors of "HexPosition"
|
/// Hexagonal position (in a hexagonal grid).
|
||||||
pub struct GroupHexPosition(pub HashSet<HexPosition>);
|
/// We are using the axial coordinate system explained in this [documentation](https://www.redblobgames.com/grids/hexagons/#coordinates).
|
||||||
|
|
||||||
impl GroupHexPosition {
|
|
||||||
/// TODO
|
|
||||||
pub fn new(hexes: HashSet<HexPosition>) -> Self {
|
|
||||||
GroupHexPosition(hexes)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Removes the origin (`HexPosition { q: 0, r: 0 }`) of a
|
|
||||||
/// "GroupHexPosition"
|
|
||||||
pub fn remove_origin(&mut self) -> &mut Self {
|
|
||||||
self.0.remove(&HexPosition { q: 0, r: 0 });
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Hex position (in a hexagonal grid).
|
|
||||||
///
|
|
||||||
/// usnig this doc : https://www.redblobgames.com/grids/hexagons/
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct HexPosition {
|
pub struct HexPosition {
|
||||||
/// Q coordinate
|
/// Q coordinate
|
||||||
|
@ -33,23 +15,36 @@ pub struct HexPosition {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HexPosition {
|
impl HexPosition {
|
||||||
/// Returns the distance between two "HexPosition"
|
/// Returns the distance between two [HexPosition]
|
||||||
|
///
|
||||||
|
/// # How does it work ?
|
||||||
|
///
|
||||||
|
/// Hexagonal grid using the [cube](https://www.redblobgames.com/grids/hexagons/#coordinates) coordinate system,
|
||||||
|
/// is like a cube in 2D space.
|
||||||
|
/// The Manhattan distance between two positions is equal to: the half of the sum of abs(dx) + abs(dy) + abs(dz)
|
||||||
pub fn distance_to(&self, other: &HexPosition) -> f32 {
|
pub fn distance_to(&self, other: &HexPosition) -> f32 {
|
||||||
((self.q - other.q).abs()
|
// dx = |x1 - x2| and x = q
|
||||||
+ (self.r - other.r).abs()
|
let dq = self.q - other.q;
|
||||||
+ (self.q + self.r - other.q - other.r).abs()) as f32
|
|
||||||
/ 2.
|
// dy = |y1 - y2| and y = r
|
||||||
|
let dr = self.r - other.r;
|
||||||
|
|
||||||
|
// dz = |z1 - z2| and z = -q - r
|
||||||
|
let ds = self.q + self.r - other.q - other.r;
|
||||||
|
|
||||||
|
// Manhattan distance = (abs(dq) + abs(dr) + abs(ds)) / 2
|
||||||
|
(dq.abs() + dr.abs() + ds.abs()) as f32 / 2.
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns all positions in a given range
|
/// Returns all positions in a given `range`.
|
||||||
pub fn range(&self, range: i32) -> GroupHexPosition {
|
pub fn range(&self, range: i32) -> HashSet<HexPosition> {
|
||||||
let mut positions = HashSet::new();
|
let mut result_positions = HashSet::new();
|
||||||
for q in (-range)..=range {
|
for q in (-range)..=range {
|
||||||
for r in (-range).max(-q - range)..=range.min(-q + range) {
|
for r in (-range).max(-q - range)..=range.min(-q + range) {
|
||||||
positions.insert(HexPosition { q, r });
|
result_positions.insert(HexPosition { q, r });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GroupHexPosition(positions)
|
result_positions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue