hexagon_map/isometric/
mod.rs1use crate::{CubicPoint, HexPoint, Joint, Orientation};
2use std::fmt::{Debug, Formatter};
3
4pub struct IsometricLine {
5 wrapper: IsometricLineSealed,
6}
7
8impl Debug for IsometricLine {
9 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
10 match self {
11 IsometricLine { wrapper: IsometricLineSealed::Zero { center, stop } } => {
12 let index = match stop {
13 true => 1,
14 false => 0,
15 };
16 f.debug_struct("IsometricLine").field("current", center).field("distance", &0).field("index", &index).finish()
17 }
18 IsometricLine { wrapper: IsometricLineSealed::Normal { current, distance, index } } => f
19 .debug_struct("IsometricLine")
20 .field("current", ¤t.target())
21 .field("distance", distance)
22 .field("index", index)
23 .finish(),
24 }
25 }
26}
27
28enum IsometricLineSealed {
29 Zero { center: CubicPoint, stop: bool },
30 Normal { current: Joint, distance: isize, index: isize },
31}
32
33impl IsometricLine {
34 pub fn new<P>(center: P, distance: usize) -> IsometricLine
35 where
36 P: HexPoint,
37 {
38 let center = center.as_cubic_point();
39 let h_offset = distance as isize;
40 let wrapper = match distance {
41 0 => IsometricLineSealed::Zero { center, stop: false },
42 _ => IsometricLineSealed::Normal {
43 current: Joint::new(CubicPoint { p: center.p + h_offset, q: center.q + h_offset - 1 }, Orientation::P(true)),
44 distance: h_offset,
45 index: 0,
46 },
47 };
48 IsometricLine { wrapper }
49 }
50 fn increase(&mut self) {
51 match &mut self.wrapper {
52 IsometricLineSealed::Zero { stop, .. } => {
53 *stop = true;
54 }
55 IsometricLineSealed::Normal { index, .. } => {
56 *index += 1;
57 }
58 }
59 }
60 pub fn is_finish(&self) -> bool {
61 match &self.wrapper {
62 IsometricLineSealed::Zero { stop, .. } => *stop,
63 IsometricLineSealed::Normal { index, distance, .. } => *index >= 6 * *distance,
64 }
65 }
66}
67
68impl Iterator for IsometricLine {
69 type Item = CubicPoint;
70
71 fn next(&mut self) -> Option<Self::Item> {
72 let mut out = None;
73 if !self.is_finish() {
74 match &mut self.wrapper {
75 IsometricLineSealed::Zero { center, .. } => out = Some(*center),
76 IsometricLineSealed::Normal { current, distance, index } => {
77 match *index % *distance {
78 0 => {
79 *current = current.forward().rotate(false);
80 out = Some(current.source().as_cubic_point());
81 }
82 _ => {
83 *current = current.forward();
84 out = Some(current.source().as_cubic_point());
85 }
86 };
87 }
88 }
89 self.increase();
90 }
91 out
92 }
93}