hexx/hex/grid/
edge.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
use crate::{EdgeDirection, Hex};
use std::ops::Neg;

use super::GridVertex;

/// Hexagonal grid orientated edge representation
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(not(target_arch = "spirv"), derive(Hash))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
pub struct GridEdge {
    /// The coordinate of the edge
    pub origin: Hex,
    /// The direction the edge points towards
    pub direction: EdgeDirection,
}

impl GridEdge {
    /// Edges are equivalent if they have identical or flipped origin or
    /// direction
    #[must_use]
    pub fn equivalent(&self, other: &Self) -> bool {
        (self.origin == other.origin && self.direction == other.direction)
            || (self.origin == other.destination() && self.direction == other.direction.const_neg())
    }

    #[inline]
    #[must_use]
    /// Returns the coordinate the edge id pointing to
    pub const fn destination(&self) -> Hex {
        self.origin.add_dir(self.direction)
    }

    #[inline]
    #[must_use]
    /// Returns the two vertices making this edge in clockwise order
    pub const fn vertices(&self) -> [GridVertex; 2] {
        [
            GridVertex {
                origin: self.origin,
                direction: self.direction.vertex_ccw(),
            },
            GridVertex {
                origin: self.origin,
                direction: self.direction.vertex_cw(),
            },
        ]
    }

    #[inline]
    #[must_use]
    /// Flips the edge, changing its `origin` to be the `destination` and
    /// inverting its direction
    pub const fn flipped(self) -> Self {
        Self {
            origin: self.destination(),
            direction: self.direction.const_neg(),
        }
    }

    #[inline]
    #[must_use]
    /// Inverts the edge, now facing the opposite direction
    pub const fn const_neg(self) -> Self {
        Self {
            direction: self.direction.const_neg(),
            ..self
        }
    }

    #[inline]
    #[must_use]
    /// Returns the next edge in clockwise order
    pub const fn clockwise(self) -> Self {
        Self {
            direction: self.direction.clockwise(),
            ..self
        }
    }

    #[inline]
    #[must_use]
    /// Returns the next edge in counter clockwise order
    pub const fn counter_clockwise(self) -> Self {
        Self {
            direction: self.direction.counter_clockwise(),
            ..self
        }
    }

    #[inline]
    #[must_use]
    /// Rotates `self` clockwise by `offset` amount.
    pub const fn rotate_cw(self, offset: u8) -> Self {
        Self {
            direction: self.direction.rotate_cw(offset),
            ..self
        }
    }
    #[inline]
    #[must_use]
    /// Rotates `self` counter clockwise by `offset` amount.
    pub const fn rotate_ccw(self, offset: u8) -> Self {
        Self {
            direction: self.direction.rotate_ccw(offset),
            ..self
        }
    }
}

impl Hex {
    #[must_use]
    #[inline]
    /// Return all 6 edges of the coordinate
    pub fn all_edges(self) -> [GridEdge; 6] {
        EdgeDirection::ALL_DIRECTIONS.map(|direction| GridEdge {
            origin: self,
            direction,
        })
    }
}

impl Neg for GridEdge {
    type Output = Self;

    #[inline]
    fn neg(self) -> Self::Output {
        self.const_neg()
    }
}

impl From<EdgeDirection> for GridEdge {
    fn from(direction: EdgeDirection) -> Self {
        Self {
            origin: Hex::ZERO,
            direction,
        }
    }
}