projective_grid/square/
alignment.rs1use crate::square::index::GridCoords;
2use serde::{Deserialize, Serialize};
3
4#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
12pub struct GridTransform {
13 pub a: i32,
15 pub b: i32,
17 pub c: i32,
19 pub d: i32,
21}
22
23impl GridTransform {
24 pub const IDENTITY: GridTransform = GridTransform {
26 a: 1,
27 b: 0,
28 c: 0,
29 d: 1,
30 };
31
32 #[inline]
34 pub fn apply(&self, i: i32, j: i32) -> GridCoords {
35 GridCoords {
36 i: self.a * i + self.b * j,
37 j: self.c * i + self.d * j,
38 }
39 }
40
41 pub fn inverse(&self) -> Option<GridTransform> {
43 let det = self.a * self.d - self.b * self.c;
44 if det != 1 && det != -1 {
45 return None;
46 }
47 Some(GridTransform {
48 a: self.d / det,
49 b: -self.b / det,
50 c: -self.c / det,
51 d: self.a / det,
52 })
53 }
54}
55
56#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
58pub struct GridAlignment {
59 pub transform: GridTransform,
61 pub translation: [i32; 2],
63}
64
65impl GridAlignment {
66 pub const IDENTITY: GridAlignment = GridAlignment {
68 transform: GridTransform::IDENTITY,
69 translation: [0, 0],
70 };
71
72 #[inline]
74 pub fn map(&self, i: i32, j: i32) -> GridCoords {
75 let g = self.transform.apply(i, j);
76 GridCoords {
77 i: g.i + self.translation[0],
78 j: g.j + self.translation[1],
79 }
80 }
81
82 pub fn inverse(&self) -> Option<GridAlignment> {
84 let inv = self.transform.inverse()?;
85 let [tx, ty] = self.translation;
86 let g = inv.apply(-tx, -ty);
87 Some(GridAlignment {
88 transform: inv,
89 translation: [g.i, g.j],
90 })
91 }
92}
93
94pub const GRID_TRANSFORMS_D4: [GridTransform; 8] = [
96 GridTransform {
98 a: 1,
99 b: 0,
100 c: 0,
101 d: 1,
102 },
103 GridTransform {
104 a: 0,
105 b: 1,
106 c: -1,
107 d: 0,
108 },
109 GridTransform {
110 a: -1,
111 b: 0,
112 c: 0,
113 d: -1,
114 },
115 GridTransform {
116 a: 0,
117 b: -1,
118 c: 1,
119 d: 0,
120 },
121 GridTransform {
123 a: -1,
124 b: 0,
125 c: 0,
126 d: 1,
127 },
128 GridTransform {
129 a: 1,
130 b: 0,
131 c: 0,
132 d: -1,
133 },
134 GridTransform {
135 a: 0,
136 b: 1,
137 c: 1,
138 d: 0,
139 },
140 GridTransform {
141 a: 0,
142 b: -1,
143 c: -1,
144 d: 0,
145 },
146];