hexmap/
fractional.rs

1use crate::hex::Hex;
2use std::ops::{Add, Div, Mul, Neg, Sub};
3
4#[derive(Debug, Copy, Clone)]
5pub struct FractionalHex {
6    pub q: f32,
7    pub r: f32,
8    pub s: f32,
9}
10
11impl FractionalHex {
12    pub const fn new(q: f32, r: f32, s: f32) -> FractionalHex {
13        FractionalHex { q, r, s }
14    }
15    pub fn add(self, rhs: FractionalHex) -> FractionalHex {
16        FractionalHex {
17            q: self.q + rhs.q,
18            r: self.r + rhs.r,
19            s: self.s + rhs.s,
20        }
21    }
22    pub fn round(&self) -> Hex {
23        let FractionalHex { q, r, s } = self;
24
25        let q_diff = diff_from_round(q);
26        let r_diff = diff_from_round(r);
27        let s_diff = diff_from_round(s);
28
29        if q_diff > r_diff && q_diff > s_diff {
30            let hi_q = (-r.round() - s.round()) as i32;
31            let r = r.round() as i32;
32            let s = s.round() as i32;
33
34            return Hex { q: hi_q, r, s };
35        } else if r_diff > s_diff {
36            let hi_r = (-q.round() - s.round()) as i32;
37            let q = q.round() as i32;
38            let s = s.round() as i32;
39
40            return Hex { q, r: hi_r, s };
41        }
42
43        let hi_s = (-q.round() - r.round()) as i32;
44        let q = q.round() as i32;
45        let r = r.round() as i32;
46
47        Hex { q, r, s: hi_s }
48    }
49}
50
51fn diff_from_round(i: &f32) -> f32 {
52    (i - i.round()).abs()
53}
54
55impl PartialEq for FractionalHex {
56    fn eq(&self, rhs: &Self) -> bool {
57        self.q == rhs.q && self.r == rhs.r && self.s == rhs.s
58    }
59}
60
61impl Add for FractionalHex {
62    type Output = FractionalHex;
63
64    fn add(self, rhs: Self) -> Self::Output {
65        FractionalHex {
66            q: self.q + rhs.q,
67            r: self.r + rhs.r,
68            s: self.s + rhs.s,
69        }
70    }
71}
72
73impl Add<Hex> for FractionalHex {
74    type Output = FractionalHex;
75
76    fn add(self, rhs: Hex) -> Self::Output {
77        FractionalHex {
78            q: (rhs.q as f32) + self.q,
79            r: (rhs.r as f32) + self.r,
80            s: (rhs.s as f32) + self.s,
81        }
82    }
83}
84
85impl Sub for FractionalHex {
86    type Output = FractionalHex;
87
88    fn sub(self, rhs: Self) -> Self::Output {
89        FractionalHex {
90            q: self.q - rhs.q,
91            r: self.r - rhs.r,
92            s: self.s - rhs.s,
93        }
94    }
95}
96
97impl Sub<Hex> for FractionalHex {
98    type Output = FractionalHex;
99
100    fn sub(self, rhs: Hex) -> Self::Output {
101        FractionalHex {
102            q: self.q - (rhs.q as f32),
103            r: self.r - (rhs.r as f32),
104            s: self.s - (rhs.s as f32),
105        }
106    }
107}
108
109impl Mul<f32> for FractionalHex {
110    type Output = FractionalHex;
111
112    fn mul(self, rhs: f32) -> Self::Output {
113        let rhs = &rhs;
114
115        FractionalHex {
116            q: self.q * rhs,
117            r: self.r * rhs,
118            s: self.s * rhs,
119        }
120    }
121}
122
123impl Div<f32> for FractionalHex {
124    type Output = FractionalHex;
125
126    fn div(self, rhs: f32) -> Self::Output {
127        let rhs = &rhs;
128
129        let q = self.q / rhs;
130        let r = self.r / rhs;
131        let s = self.s / rhs;
132
133        FractionalHex { q, r, s }
134    }
135}
136
137impl Neg for FractionalHex {
138    type Output = FractionalHex;
139
140    fn neg(self) -> Self::Output {
141        FractionalHex::new(-self.q, -self.r, -self.s)
142    }
143}