Skip to main content

loam_shape/
polytope_geom.rs

1//! Every generator here is origin-centered at circumradius `r`.
2
3use glam::Vec4;
4
5pub fn pentatope_vertices(r: f32) -> Vec<Vec4> {
6    let k = r;
7    let base_w = -r * 0.25;
8    let base_r = r * (15.0_f32).sqrt() / 4.0;
9    let t = base_r / 3.0_f32.sqrt();
10    vec![
11        Vec4::new(0.0, 0.0, 0.0, k),
12        Vec4::new(t, t, t, base_w),
13        Vec4::new(t, -t, -t, base_w),
14        Vec4::new(-t, t, -t, base_w),
15        Vec4::new(-t, -t, t, base_w),
16    ]
17}
18
19pub fn tesseract_vertices(r: f32) -> Vec<Vec4> {
20    let a = r * 0.5;
21    let mut v = Vec::with_capacity(16);
22    for &w in &[-a, a] {
23        for &z in &[-a, a] {
24            for &y in &[-a, a] {
25                for &x in &[-a, a] {
26                    v.push(Vec4::new(x, y, z, w));
27                }
28            }
29        }
30    }
31    v
32}
33
34pub fn cell16_vertices(r: f32) -> Vec<Vec4> {
35    vec![
36        Vec4::new(r, 0.0, 0.0, 0.0),
37        Vec4::new(-r, 0.0, 0.0, 0.0),
38        Vec4::new(0.0, r, 0.0, 0.0),
39        Vec4::new(0.0, -r, 0.0, 0.0),
40        Vec4::new(0.0, 0.0, r, 0.0),
41        Vec4::new(0.0, 0.0, -r, 0.0),
42        Vec4::new(0.0, 0.0, 0.0, r),
43        Vec4::new(0.0, 0.0, 0.0, -r),
44    ]
45}
46
47pub fn cell24_vertices(r: f32) -> Vec<Vec4> {
48    let k = r / 2.0_f32.sqrt();
49    let mut v = Vec::with_capacity(24);
50    for i in 0..4 {
51        for j in (i + 1)..4 {
52            for &si in &[-k, k] {
53                for &sj in &[-k, k] {
54                    let mut c = [0.0_f32; 4];
55                    c[i] = si;
56                    c[j] = sj;
57                    v.push(Vec4::new(c[0], c[1], c[2], c[3]));
58                }
59            }
60        }
61    }
62    v
63}
64
65fn even_permutations_4<T: Copy>(arr: [T; 4]) -> [[T; 4]; 12] {
66    [
67        [arr[0], arr[1], arr[2], arr[3]],
68        [arr[1], arr[2], arr[0], arr[3]],
69        [arr[2], arr[0], arr[1], arr[3]],
70        [arr[1], arr[3], arr[2], arr[0]],
71        [arr[3], arr[0], arr[2], arr[1]],
72        [arr[2], arr[1], arr[3], arr[0]],
73        [arr[3], arr[1], arr[0], arr[2]],
74        [arr[0], arr[2], arr[3], arr[1]],
75        [arr[0], arr[3], arr[1], arr[2]],
76        [arr[1], arr[0], arr[3], arr[2]],
77        [arr[2], arr[3], arr[0], arr[1]],
78        [arr[3], arr[2], arr[1], arr[0]],
79    ]
80}
81
82/// Vertex set at circumradius 1 (Wikipedia "600-cell").
83pub fn cell600_vertices(r: f32) -> Vec<Vec4> {
84    let phi = (1.0 + 5.0_f32.sqrt()) * 0.5;
85    let mut v = Vec::with_capacity(120);
86
87    for axis in 0..4 {
88        for sign in [r, -r] {
89            let mut c = [0.0_f32; 4];
90            c[axis] = sign;
91            v.push(Vec4::from_array(c));
92        }
93    }
94
95    let h = r * 0.5;
96    for s in 0..16u32 {
97        let x = if s & 1 == 1 { -h } else { h };
98        let y = if (s >> 1) & 1 == 1 { -h } else { h };
99        let z = if (s >> 2) & 1 == 1 { -h } else { h };
100        let w = if (s >> 3) & 1 == 1 { -h } else { h };
101        v.push(Vec4::new(x, y, z, w));
102    }
103
104    let base = [0.0_f32, r * 0.5, r * phi * 0.5, r / (2.0 * phi)];
105    for perm in even_permutations_4(base) {
106        for sign_mask in 0..8u32 {
107            let mut x = perm;
108            let mut k = 0usize;
109            for xi in x.iter_mut() {
110                if *xi != 0.0 {
111                    if (sign_mask >> k) & 1 == 1 {
112                        *xi = -*xi;
113                    }
114                    k += 1;
115                }
116            }
117            v.push(Vec4::from_array(x));
118        }
119    }
120
121    v
122}
123
124/// Vertex set at circumradius `2√2` before rescaling (Wikipedia "120-cell").
125pub fn cell120_vertices(r: f32) -> Vec<Vec4> {
126    let phi = (1.0 + 5.0_f32.sqrt()) * 0.5;
127    let phi2 = phi * phi;
128    let inv_phi = 1.0 / phi;
129    let inv_phi2 = inv_phi * inv_phi;
130    let sqrt5 = 5.0_f32.sqrt();
131    let scale = r / (2.0 * 2.0_f32.sqrt());
132    let mut v = Vec::with_capacity(600);
133
134    for i in 0..4 {
135        for j in (i + 1)..4 {
136            for si in [2.0_f32, -2.0] {
137                for sj in [2.0_f32, -2.0] {
138                    let mut c = [0.0_f32; 4];
139                    c[i] = si * scale;
140                    c[j] = sj * scale;
141                    v.push(Vec4::from_array(c));
142                }
143            }
144        }
145    }
146
147    let mut emit_one_special = |special: f32, common: f32| {
148        for special_pos in 0..4 {
149            for sm in 0..16u32 {
150                let mut c = [0.0_f32; 4];
151                for (i, ci) in c.iter_mut().enumerate() {
152                    let val = if i == special_pos { special } else { common };
153                    let sign = if (sm >> i) & 1 == 1 { -1.0 } else { 1.0 };
154                    *ci = val * sign * scale;
155                }
156                v.push(Vec4::from_array(c));
157            }
158        }
159    };
160
161    emit_one_special(sqrt5, 1.0);
162    emit_one_special(phi2, inv_phi);
163    emit_one_special(inv_phi2, phi);
164
165    let mut emit_even_zero = |a: f32, b: f32, c: f32| {
166        let base = [0.0_f32, a, b, c];
167        for perm in even_permutations_4(base) {
168            for sign_mask in 0..8u32 {
169                let mut x = perm;
170                let mut k = 0usize;
171                for xi in x.iter_mut() {
172                    if *xi != 0.0 {
173                        if (sign_mask >> k) & 1 == 1 {
174                            *xi = -*xi;
175                        }
176                        k += 1;
177                    }
178                }
179                for ci in &mut x {
180                    *ci *= scale;
181                }
182                v.push(Vec4::from_array(x));
183            }
184        }
185    };
186
187    emit_even_zero(inv_phi2, 1.0, phi2);
188    emit_even_zero(inv_phi, phi, sqrt5);
189
190    let base7 = [inv_phi, 1.0, phi, 2.0_f32];
191    for perm in even_permutations_4(base7) {
192        for sm in 0..16u32 {
193            let mut x = perm;
194            for (i, xi) in x.iter_mut().enumerate() {
195                if (sm >> i) & 1 == 1 {
196                    *xi = -*xi;
197                }
198            }
199            for ci in &mut x {
200                *ci *= scale;
201            }
202            v.push(Vec4::from_array(x));
203        }
204    }
205
206    v
207}