hexagon_map/point/
mod.rs

1use crate::{direction::Orientation, AxialPoint, CubicPoint, Joint};
2use serde::{Deserialize, Serialize};
3use std::fmt::{Debug, Display, Formatter};
4
5pub mod a_point;
6pub mod c_point;
7pub mod h_point;
8pub mod w_point;
9
10mod arithmetic;
11mod convert;
12mod display;
13
14pub trait HexPoint: Copy + Eq + Ord + Display + Debug {
15    /// Create a new point in cubic coordinates
16    fn as_cubic_point(&self) -> CubicPoint;
17    /// Create a new point in axial coordinates from pixel coordinates
18    fn as_axial_point(&self) -> AxialPoint;
19    fn as_joint(&self, direction: Orientation) -> Joint {
20        Joint::new(*self, direction)
21    }
22    fn go(&self, direction: Orientation) -> CubicPoint {
23        self.as_joint(direction).target()
24    }
25    /// Get the pixel coordinates of the center of the hexagon
26    fn get_pixel_center(&self, radius: f64) -> (f64, f64) {
27        let axial = self.as_axial_point();
28        let x = radius * 3.0f64.sqrt() * (axial.q as f64 + axial.r as f64 / 2.0);
29        let y = radius * 3.0 / 2.0 * axial.r as f64;
30        (x, y)
31    }
32    /// Get the pixel coordinates of the corners of the hexagon
33    fn get_pixel_corners(&self, radius: f64) -> [(f64, f64); 6] {
34        let (center_x, center_y) = self.get_pixel_center(radius);
35        let mut corners = [(0.0, 0.0); 6];
36        for i in 0..6 {
37            let angle = 2.0 * std::f64::consts::PI * (i as f64) / 6.0;
38            corners[i] = (center_x + radius * angle.cos(), center_y + radius * angle.sin());
39        }
40        corners
41    }
42    /// Calculate the manhattan distance between two points
43    fn taxicab_distance<P>(&self, other: P) -> usize
44    where
45        P: HexPoint,
46    {
47        let lhs = self.as_axial_point();
48        let rhs = other.as_axial_point();
49        let add = (lhs.q - rhs.q).abs() + (lhs.r - rhs.r).abs();
50        add as usize
51    }
52    /// Calculate the euclidean distance between two points
53    fn euclidean_distance<P>(&self, other: P, radius: f64) -> f64
54    where
55        P: HexPoint,
56    {
57        let (x1, y1) = self.get_pixel_center(radius);
58        let (x2, y2) = other.get_pixel_center(radius);
59        ((x1 - x2).powi(2) + (y1 - y2).powi(2)).sqrt()
60    }
61}