hexagon_map/direction/
mod.rs

1use crate::{CubicPoint, HexPoint};
2mod convert;
3mod display;
4use serde::{Deserialize, Serialize};
5
6/// Orientation in the HPQ coordinate system
7#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Serialize, Deserialize)]
8pub enum Orientation {
9    /// The horizontal axis
10    /// - `T`: move to right
11    /// - `F`: move to left
12    H(bool),
13    /// The right up axis
14    /// - `T`: move to right up
15    /// - `F`: move to left down
16    P(bool),
17    /// The left up axis
18    /// - `T`: move to left up
19    /// - `F`: move to right down
20    Q(bool),
21}
22
23impl Default for Orientation {
24    fn default() -> Self {
25        Orientation::H(true)
26    }
27}
28
29impl Orientation {
30    pub fn all() -> [Orientation; 6] {
31        [
32            Orientation::H(true),
33            Orientation::P(true),
34            Orientation::Q(true),
35            Orientation::H(false),
36            Orientation::P(false),
37            Orientation::Q(false),
38        ]
39    }
40    pub fn rotate(&self, clockwise: bool) -> Self {
41        match clockwise {
42            true => match self {
43                Orientation::H(true) => Orientation::Q(false),
44                Orientation::P(true) => Orientation::H(true),
45                Orientation::Q(true) => Orientation::P(true),
46                Orientation::H(false) => Orientation::Q(true),
47                Orientation::P(false) => Orientation::H(false),
48                Orientation::Q(false) => Orientation::P(false),
49            },
50            false => match self {
51                Orientation::H(true) => Orientation::P(true),
52                Orientation::P(true) => Orientation::Q(true),
53                Orientation::Q(true) => Orientation::H(false),
54                Orientation::H(false) => Orientation::P(false),
55                Orientation::P(false) => Orientation::Q(false),
56                Orientation::Q(false) => Orientation::H(true),
57            },
58        }
59    }
60}
61impl Orientation {
62    pub fn from_points<L, R>(lhs: L, rhs: R) -> Option<Self>
63    where
64        L: HexPoint,
65        R: HexPoint,
66    {
67        let lhs = lhs.as_cubic_point();
68        let rhs = rhs.as_cubic_point();
69        let dp = rhs.p - lhs.p;
70        let dq = rhs.q - lhs.q;
71        match (dp, dq) {
72            (1, 1) => Some(Orientation::H(true)),
73            (1, 0) => Some(Orientation::P(true)),
74            (0, 1) => Some(Orientation::Q(true)),
75            (-1, -1) => Some(Orientation::H(false)),
76            (-1, 0) => Some(Orientation::P(false)),
77            (0, -1) => Some(Orientation::Q(false)),
78            _ => None,
79        }
80    }
81    pub fn goto_points(&self, lhs: CubicPoint) -> CubicPoint {
82        let CubicPoint { p, q } = lhs;
83        let cubic = match self {
84            Orientation::H(true) => CubicPoint::new(p + 1, q + 1),
85            Orientation::P(true) => CubicPoint::new(p + 1, q),
86            Orientation::Q(true) => CubicPoint::new(p, q + 1),
87            Orientation::H(false) => CubicPoint::new(p - 1, q - 1),
88            Orientation::P(false) => CubicPoint::new(p - 1, q),
89            Orientation::Q(false) => CubicPoint::new(p, q - 1),
90        };
91        cubic
92    }
93}