Merge pull request 'feature-120-cell-more-inscriptions' (#24) from feature-120-cell-more-inscriptions into main
Reviewed-on: #24
This commit is contained in:
commit
db7e2c41b2
@ -1,6 +1,11 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
## v1.1 - 1/1/2025
|
||||||
|
|
||||||
|
The 120-cell now includes a visualisation of its inscribed 5-cells, which honestly
|
||||||
|
looks like less of a mess than I expected it to.
|
||||||
|
|
||||||
## v1.0 - 16/11/2025
|
## v1.0 - 16/11/2025
|
||||||
|
|
||||||
It's been [two years](https://mikelynch.org/2023/Sep/02/120-cell/)</a> since
|
It's been [two years](https://mikelynch.org/2023/Sep/02/120-cell/)</a> since
|
||||||
|
|||||||
26
NOTES.md
Normal file
26
NOTES.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# NOTES
|
||||||
|
|
||||||
|
|
||||||
|
New approach for the 5-cells:
|
||||||
|
|
||||||
|
Pick a tetrahedron of an inscribed 600-cell with vertices A, B, C, D
|
||||||
|
|
||||||
|
This gives pairs of vertices:
|
||||||
|
|
||||||
|
AB
|
||||||
|
AC
|
||||||
|
AD
|
||||||
|
BC
|
||||||
|
BD
|
||||||
|
CD
|
||||||
|
|
||||||
|
Each of these gives rise to seven pairs of 5-cells which are on neighboring vertices
|
||||||
|
of the 5 600-cells.
|
||||||
|
|
||||||
|
Try enumerating these and inspecting them to find one or more coherent sets of four
|
||||||
|
5-cells which lie on one tetrahedron from each of the 600-cells.
|
||||||
|
|
||||||
|
(I expect there to be more than one, like how there are two ways to partition the
|
||||||
|
120-cell vertices into 600-cells)
|
||||||
|
|
||||||
|
|
||||||
849
cellindex.js
849
cellindex.js
@ -104,6 +104,855 @@ export const LAYERS120 = {
|
|||||||
163,219,271,223,167]
|
163,219,271,223,167]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const CELL120_CELL5 = {
|
||||||
|
"tetras": {
|
||||||
|
},
|
||||||
|
"cell5s": {
|
||||||
|
"1": [
|
||||||
|
27,
|
||||||
|
28,
|
||||||
|
264,
|
||||||
|
309,
|
||||||
|
275
|
||||||
|
],
|
||||||
|
"2": [
|
||||||
|
223,
|
||||||
|
76,
|
||||||
|
238,
|
||||||
|
84,
|
||||||
|
225
|
||||||
|
],
|
||||||
|
"3": [
|
||||||
|
253,
|
||||||
|
44,
|
||||||
|
283,
|
||||||
|
304,
|
||||||
|
42
|
||||||
|
],
|
||||||
|
"4": [
|
||||||
|
419,
|
||||||
|
112,
|
||||||
|
197,
|
||||||
|
578,
|
||||||
|
521
|
||||||
|
],
|
||||||
|
"5": [
|
||||||
|
339,
|
||||||
|
14,
|
||||||
|
384,
|
||||||
|
382,
|
||||||
|
337
|
||||||
|
],
|
||||||
|
"6": [
|
||||||
|
331,
|
||||||
|
4,
|
||||||
|
335,
|
||||||
|
390,
|
||||||
|
386
|
||||||
|
],
|
||||||
|
"7": [
|
||||||
|
427,
|
||||||
|
160,
|
||||||
|
551,
|
||||||
|
146,
|
||||||
|
557
|
||||||
|
],
|
||||||
|
"8": [
|
||||||
|
265,
|
||||||
|
60,
|
||||||
|
64,
|
||||||
|
295,
|
||||||
|
246
|
||||||
|
],
|
||||||
|
"9": [
|
||||||
|
473,
|
||||||
|
100,
|
||||||
|
495,
|
||||||
|
213,
|
||||||
|
462
|
||||||
|
],
|
||||||
|
"10": [
|
||||||
|
393,
|
||||||
|
6,
|
||||||
|
328,
|
||||||
|
397,
|
||||||
|
326
|
||||||
|
],
|
||||||
|
"11": [
|
||||||
|
539,
|
||||||
|
164,
|
||||||
|
439,
|
||||||
|
561,
|
||||||
|
142
|
||||||
|
],
|
||||||
|
"12": [
|
||||||
|
511,
|
||||||
|
122,
|
||||||
|
456,
|
||||||
|
595,
|
||||||
|
181
|
||||||
|
],
|
||||||
|
"13": [
|
||||||
|
555,
|
||||||
|
154,
|
||||||
|
152,
|
||||||
|
545,
|
||||||
|
429
|
||||||
|
],
|
||||||
|
"14": [
|
||||||
|
95,
|
||||||
|
202,
|
||||||
|
486,
|
||||||
|
500,
|
||||||
|
465
|
||||||
|
],
|
||||||
|
"15": [
|
||||||
|
471,
|
||||||
|
208,
|
||||||
|
502,
|
||||||
|
484,
|
||||||
|
89
|
||||||
|
],
|
||||||
|
"16": [
|
||||||
|
347,
|
||||||
|
21,
|
||||||
|
348,
|
||||||
|
374,
|
||||||
|
373
|
||||||
|
],
|
||||||
|
"17": [
|
||||||
|
487,
|
||||||
|
203,
|
||||||
|
94,
|
||||||
|
468,
|
||||||
|
497
|
||||||
|
],
|
||||||
|
"18": [
|
||||||
|
165,
|
||||||
|
139,
|
||||||
|
542,
|
||||||
|
568,
|
||||||
|
434
|
||||||
|
],
|
||||||
|
"19": [
|
||||||
|
367,
|
||||||
|
18,
|
||||||
|
355,
|
||||||
|
368,
|
||||||
|
353
|
||||||
|
],
|
||||||
|
"20": [
|
||||||
|
231,
|
||||||
|
78,
|
||||||
|
86,
|
||||||
|
236,
|
||||||
|
217
|
||||||
|
],
|
||||||
|
"21": [
|
||||||
|
356,
|
||||||
|
17,
|
||||||
|
366,
|
||||||
|
354,
|
||||||
|
365
|
||||||
|
],
|
||||||
|
"22": [
|
||||||
|
503,
|
||||||
|
205,
|
||||||
|
470,
|
||||||
|
92,
|
||||||
|
481
|
||||||
|
],
|
||||||
|
"23": [
|
||||||
|
527,
|
||||||
|
106,
|
||||||
|
584,
|
||||||
|
195,
|
||||||
|
421
|
||||||
|
],
|
||||||
|
"24": [
|
||||||
|
239,
|
||||||
|
73,
|
||||||
|
222,
|
||||||
|
228,
|
||||||
|
81
|
||||||
|
],
|
||||||
|
"25": [
|
||||||
|
543,
|
||||||
|
138,
|
||||||
|
168,
|
||||||
|
435,
|
||||||
|
565
|
||||||
|
],
|
||||||
|
"26": [
|
||||||
|
48,
|
||||||
|
46,
|
||||||
|
302,
|
||||||
|
281,
|
||||||
|
255
|
||||||
|
],
|
||||||
|
"27": [
|
||||||
|
248,
|
||||||
|
62,
|
||||||
|
293,
|
||||||
|
58,
|
||||||
|
267
|
||||||
|
],
|
||||||
|
"28": [
|
||||||
|
440,
|
||||||
|
141,
|
||||||
|
562,
|
||||||
|
540,
|
||||||
|
163
|
||||||
|
],
|
||||||
|
"29": [
|
||||||
|
274,
|
||||||
|
30,
|
||||||
|
312,
|
||||||
|
261,
|
||||||
|
29
|
||||||
|
],
|
||||||
|
"30": [
|
||||||
|
179,
|
||||||
|
128,
|
||||||
|
597,
|
||||||
|
450,
|
||||||
|
505
|
||||||
|
],
|
||||||
|
"31": [
|
||||||
|
376,
|
||||||
|
22,
|
||||||
|
375,
|
||||||
|
346,
|
||||||
|
345
|
||||||
|
],
|
||||||
|
"32": [
|
||||||
|
320,
|
||||||
|
11,
|
||||||
|
405,
|
||||||
|
401,
|
||||||
|
319
|
||||||
|
],
|
||||||
|
"33": [
|
||||||
|
448,
|
||||||
|
173,
|
||||||
|
130,
|
||||||
|
587,
|
||||||
|
519
|
||||||
|
],
|
||||||
|
"34": [
|
||||||
|
460,
|
||||||
|
102,
|
||||||
|
211,
|
||||||
|
489,
|
||||||
|
479
|
||||||
|
],
|
||||||
|
"35": [
|
||||||
|
388,
|
||||||
|
2,
|
||||||
|
392,
|
||||||
|
329,
|
||||||
|
333
|
||||||
|
],
|
||||||
|
"36": [
|
||||||
|
512,
|
||||||
|
182,
|
||||||
|
596,
|
||||||
|
121,
|
||||||
|
455
|
||||||
|
],
|
||||||
|
"37": [
|
||||||
|
592,
|
||||||
|
170,
|
||||||
|
516,
|
||||||
|
443,
|
||||||
|
133
|
||||||
|
],
|
||||||
|
"38": [
|
||||||
|
120,
|
||||||
|
189,
|
||||||
|
529,
|
||||||
|
570,
|
||||||
|
411
|
||||||
|
],
|
||||||
|
"39": [
|
||||||
|
420,
|
||||||
|
198,
|
||||||
|
577,
|
||||||
|
522,
|
||||||
|
111
|
||||||
|
],
|
||||||
|
"40": [
|
||||||
|
272,
|
||||||
|
69,
|
||||||
|
65,
|
||||||
|
290,
|
||||||
|
243
|
||||||
|
],
|
||||||
|
"41": [
|
||||||
|
488,
|
||||||
|
93,
|
||||||
|
498,
|
||||||
|
204,
|
||||||
|
467
|
||||||
|
],
|
||||||
|
"42": [
|
||||||
|
156,
|
||||||
|
150,
|
||||||
|
547,
|
||||||
|
553,
|
||||||
|
431
|
||||||
|
],
|
||||||
|
"43": [
|
||||||
|
252,
|
||||||
|
53,
|
||||||
|
286,
|
||||||
|
297,
|
||||||
|
55
|
||||||
|
],
|
||||||
|
"44": [
|
||||||
|
532,
|
||||||
|
192,
|
||||||
|
117,
|
||||||
|
410,
|
||||||
|
571
|
||||||
|
],
|
||||||
|
"45": [
|
||||||
|
400,
|
||||||
|
7,
|
||||||
|
321,
|
||||||
|
396,
|
||||||
|
323
|
||||||
|
],
|
||||||
|
"46": [
|
||||||
|
580,
|
||||||
|
199,
|
||||||
|
417,
|
||||||
|
110,
|
||||||
|
523
|
||||||
|
],
|
||||||
|
"47": [
|
||||||
|
296,
|
||||||
|
63,
|
||||||
|
245,
|
||||||
|
266,
|
||||||
|
59
|
||||||
|
],
|
||||||
|
"48": [
|
||||||
|
600,
|
||||||
|
125,
|
||||||
|
178,
|
||||||
|
508,
|
||||||
|
451
|
||||||
|
],
|
||||||
|
"49": [
|
||||||
|
68,
|
||||||
|
72,
|
||||||
|
269,
|
||||||
|
242,
|
||||||
|
291
|
||||||
|
],
|
||||||
|
"50": [
|
||||||
|
324,
|
||||||
|
8,
|
||||||
|
399,
|
||||||
|
322,
|
||||||
|
395
|
||||||
|
],
|
||||||
|
"51": [
|
||||||
|
499,
|
||||||
|
96,
|
||||||
|
485,
|
||||||
|
466,
|
||||||
|
201
|
||||||
|
],
|
||||||
|
"52": [
|
||||||
|
406,
|
||||||
|
12,
|
||||||
|
317,
|
||||||
|
318,
|
||||||
|
402
|
||||||
|
],
|
||||||
|
"53": [
|
||||||
|
563,
|
||||||
|
144,
|
||||||
|
437,
|
||||||
|
162,
|
||||||
|
537
|
||||||
|
],
|
||||||
|
"54": [
|
||||||
|
234,
|
||||||
|
88,
|
||||||
|
219,
|
||||||
|
229,
|
||||||
|
80
|
||||||
|
],
|
||||||
|
"55": [
|
||||||
|
350,
|
||||||
|
24,
|
||||||
|
349,
|
||||||
|
371,
|
||||||
|
372
|
||||||
|
],
|
||||||
|
"56": [
|
||||||
|
444,
|
||||||
|
134,
|
||||||
|
515,
|
||||||
|
169,
|
||||||
|
591
|
||||||
|
],
|
||||||
|
"57": [
|
||||||
|
258,
|
||||||
|
40,
|
||||||
|
39,
|
||||||
|
277,
|
||||||
|
307
|
||||||
|
],
|
||||||
|
"58": [
|
||||||
|
285,
|
||||||
|
56,
|
||||||
|
251,
|
||||||
|
54,
|
||||||
|
298
|
||||||
|
],
|
||||||
|
"59": [
|
||||||
|
546,
|
||||||
|
151,
|
||||||
|
153,
|
||||||
|
430,
|
||||||
|
556
|
||||||
|
],
|
||||||
|
"60": [
|
||||||
|
98,
|
||||||
|
215,
|
||||||
|
475,
|
||||||
|
493,
|
||||||
|
464
|
||||||
|
],
|
||||||
|
"61": [
|
||||||
|
474,
|
||||||
|
214,
|
||||||
|
99,
|
||||||
|
461,
|
||||||
|
496
|
||||||
|
],
|
||||||
|
"62": [
|
||||||
|
357,
|
||||||
|
20,
|
||||||
|
363,
|
||||||
|
359,
|
||||||
|
364
|
||||||
|
],
|
||||||
|
"63": [
|
||||||
|
490,
|
||||||
|
212,
|
||||||
|
459,
|
||||||
|
101,
|
||||||
|
480
|
||||||
|
],
|
||||||
|
"64": [
|
||||||
|
185,
|
||||||
|
116,
|
||||||
|
415,
|
||||||
|
533,
|
||||||
|
574
|
||||||
|
],
|
||||||
|
"65": [
|
||||||
|
378,
|
||||||
|
16,
|
||||||
|
343,
|
||||||
|
341,
|
||||||
|
380
|
||||||
|
],
|
||||||
|
"66": [
|
||||||
|
218,
|
||||||
|
85,
|
||||||
|
235,
|
||||||
|
77,
|
||||||
|
232
|
||||||
|
],
|
||||||
|
"67": [
|
||||||
|
342,
|
||||||
|
15,
|
||||||
|
377,
|
||||||
|
379,
|
||||||
|
344
|
||||||
|
],
|
||||||
|
"68": [
|
||||||
|
458,
|
||||||
|
209,
|
||||||
|
491,
|
||||||
|
477,
|
||||||
|
104
|
||||||
|
],
|
||||||
|
"69": [
|
||||||
|
514,
|
||||||
|
135,
|
||||||
|
441,
|
||||||
|
590,
|
||||||
|
172
|
||||||
|
],
|
||||||
|
"70": [
|
||||||
|
226,
|
||||||
|
83,
|
||||||
|
75,
|
||||||
|
237,
|
||||||
|
224
|
||||||
|
],
|
||||||
|
"71": [
|
||||||
|
530,
|
||||||
|
119,
|
||||||
|
569,
|
||||||
|
190,
|
||||||
|
412
|
||||||
|
],
|
||||||
|
"72": [
|
||||||
|
38,
|
||||||
|
37,
|
||||||
|
257,
|
||||||
|
308,
|
||||||
|
278
|
||||||
|
],
|
||||||
|
"73": [
|
||||||
|
414,
|
||||||
|
113,
|
||||||
|
188,
|
||||||
|
575,
|
||||||
|
536
|
||||||
|
],
|
||||||
|
"74": [
|
||||||
|
362,
|
||||||
|
19,
|
||||||
|
358,
|
||||||
|
361,
|
||||||
|
360
|
||||||
|
],
|
||||||
|
"75": [
|
||||||
|
334,
|
||||||
|
1,
|
||||||
|
330,
|
||||||
|
387,
|
||||||
|
391
|
||||||
|
],
|
||||||
|
"76": [
|
||||||
|
438,
|
||||||
|
161,
|
||||||
|
538,
|
||||||
|
143,
|
||||||
|
564
|
||||||
|
],
|
||||||
|
"77": [
|
||||||
|
550,
|
||||||
|
157,
|
||||||
|
426,
|
||||||
|
560,
|
||||||
|
147
|
||||||
|
],
|
||||||
|
"78": [
|
||||||
|
566,
|
||||||
|
167,
|
||||||
|
137,
|
||||||
|
544,
|
||||||
|
436
|
||||||
|
],
|
||||||
|
"79": [
|
||||||
|
126,
|
||||||
|
177,
|
||||||
|
452,
|
||||||
|
507,
|
||||||
|
599
|
||||||
|
],
|
||||||
|
"80": [
|
||||||
|
284,
|
||||||
|
41,
|
||||||
|
254,
|
||||||
|
43,
|
||||||
|
303
|
||||||
|
],
|
||||||
|
"81": [
|
||||||
|
494,
|
||||||
|
97,
|
||||||
|
476,
|
||||||
|
463,
|
||||||
|
216
|
||||||
|
],
|
||||||
|
"82": [
|
||||||
|
200,
|
||||||
|
109,
|
||||||
|
418,
|
||||||
|
524,
|
||||||
|
579
|
||||||
|
],
|
||||||
|
"83": [
|
||||||
|
263,
|
||||||
|
25,
|
||||||
|
26,
|
||||||
|
276,
|
||||||
|
310
|
||||||
|
],
|
||||||
|
"84": [
|
||||||
|
300,
|
||||||
|
50,
|
||||||
|
52,
|
||||||
|
249,
|
||||||
|
287
|
||||||
|
],
|
||||||
|
"85": [
|
||||||
|
558,
|
||||||
|
145,
|
||||||
|
428,
|
||||||
|
159,
|
||||||
|
552
|
||||||
|
],
|
||||||
|
"86": [
|
||||||
|
403,
|
||||||
|
9,
|
||||||
|
316,
|
||||||
|
315,
|
||||||
|
407
|
||||||
|
],
|
||||||
|
"87": [
|
||||||
|
74,
|
||||||
|
82,
|
||||||
|
227,
|
||||||
|
221,
|
||||||
|
240
|
||||||
|
],
|
||||||
|
"88": [
|
||||||
|
289,
|
||||||
|
66,
|
||||||
|
244,
|
||||||
|
271,
|
||||||
|
70
|
||||||
|
],
|
||||||
|
"89": [
|
||||||
|
306,
|
||||||
|
34,
|
||||||
|
280,
|
||||||
|
33,
|
||||||
|
259
|
||||||
|
],
|
||||||
|
"90": [
|
||||||
|
572,
|
||||||
|
118,
|
||||||
|
531,
|
||||||
|
409,
|
||||||
|
191
|
||||||
|
],
|
||||||
|
"91": [
|
||||||
|
207,
|
||||||
|
90,
|
||||||
|
472,
|
||||||
|
483,
|
||||||
|
501
|
||||||
|
],
|
||||||
|
"92": [
|
||||||
|
369,
|
||||||
|
23,
|
||||||
|
370,
|
||||||
|
351,
|
||||||
|
352
|
||||||
|
],
|
||||||
|
"93": [
|
||||||
|
585,
|
||||||
|
132,
|
||||||
|
175,
|
||||||
|
517,
|
||||||
|
446
|
||||||
|
],
|
||||||
|
"94": [
|
||||||
|
105,
|
||||||
|
196,
|
||||||
|
528,
|
||||||
|
583,
|
||||||
|
422
|
||||||
|
],
|
||||||
|
"95": [
|
||||||
|
241,
|
||||||
|
67,
|
||||||
|
292,
|
||||||
|
71,
|
||||||
|
270
|
||||||
|
],
|
||||||
|
"96": [
|
||||||
|
425,
|
||||||
|
148,
|
||||||
|
559,
|
||||||
|
549,
|
||||||
|
158
|
||||||
|
],
|
||||||
|
"97": [
|
||||||
|
525,
|
||||||
|
193,
|
||||||
|
108,
|
||||||
|
423,
|
||||||
|
582
|
||||||
|
],
|
||||||
|
"98": [
|
||||||
|
174,
|
||||||
|
129,
|
||||||
|
588,
|
||||||
|
447,
|
||||||
|
520
|
||||||
|
],
|
||||||
|
"99": [
|
||||||
|
313,
|
||||||
|
10,
|
||||||
|
404,
|
||||||
|
408,
|
||||||
|
314
|
||||||
|
],
|
||||||
|
"100": [
|
||||||
|
413,
|
||||||
|
187,
|
||||||
|
576,
|
||||||
|
535,
|
||||||
|
114
|
||||||
|
],
|
||||||
|
"101": [
|
||||||
|
573,
|
||||||
|
186,
|
||||||
|
416,
|
||||||
|
115,
|
||||||
|
534
|
||||||
|
],
|
||||||
|
"102": [
|
||||||
|
49,
|
||||||
|
51,
|
||||||
|
299,
|
||||||
|
288,
|
||||||
|
250
|
||||||
|
],
|
||||||
|
"103": [
|
||||||
|
449,
|
||||||
|
180,
|
||||||
|
127,
|
||||||
|
598,
|
||||||
|
506
|
||||||
|
],
|
||||||
|
"104": [
|
||||||
|
469,
|
||||||
|
91,
|
||||||
|
206,
|
||||||
|
504,
|
||||||
|
482
|
||||||
|
],
|
||||||
|
"105": [
|
||||||
|
513,
|
||||||
|
171,
|
||||||
|
589,
|
||||||
|
136,
|
||||||
|
442
|
||||||
|
],
|
||||||
|
"106": [
|
||||||
|
279,
|
||||||
|
35,
|
||||||
|
305,
|
||||||
|
260,
|
||||||
|
36
|
||||||
|
],
|
||||||
|
"107": [
|
||||||
|
389,
|
||||||
|
3,
|
||||||
|
385,
|
||||||
|
336,
|
||||||
|
332
|
||||||
|
],
|
||||||
|
"108": [
|
||||||
|
593,
|
||||||
|
183,
|
||||||
|
509,
|
||||||
|
454,
|
||||||
|
124
|
||||||
|
],
|
||||||
|
"109": [
|
||||||
|
149,
|
||||||
|
155,
|
||||||
|
554,
|
||||||
|
432,
|
||||||
|
548
|
||||||
|
],
|
||||||
|
"110": [
|
||||||
|
325,
|
||||||
|
5,
|
||||||
|
394,
|
||||||
|
327,
|
||||||
|
398
|
||||||
|
],
|
||||||
|
"111": [
|
||||||
|
453,
|
||||||
|
123,
|
||||||
|
510,
|
||||||
|
184,
|
||||||
|
594
|
||||||
|
],
|
||||||
|
"112": [
|
||||||
|
383,
|
||||||
|
13,
|
||||||
|
338,
|
||||||
|
340,
|
||||||
|
381
|
||||||
|
],
|
||||||
|
"113": [
|
||||||
|
311,
|
||||||
|
31,
|
||||||
|
273,
|
||||||
|
32,
|
||||||
|
262
|
||||||
|
],
|
||||||
|
"114": [
|
||||||
|
581,
|
||||||
|
107,
|
||||||
|
526,
|
||||||
|
424,
|
||||||
|
194
|
||||||
|
],
|
||||||
|
"115": [
|
||||||
|
61,
|
||||||
|
57,
|
||||||
|
268,
|
||||||
|
247,
|
||||||
|
294
|
||||||
|
],
|
||||||
|
"116": [
|
||||||
|
87,
|
||||||
|
79,
|
||||||
|
230,
|
||||||
|
220,
|
||||||
|
233
|
||||||
|
],
|
||||||
|
"117": [
|
||||||
|
301,
|
||||||
|
47,
|
||||||
|
45,
|
||||||
|
256,
|
||||||
|
282
|
||||||
|
],
|
||||||
|
"118": [
|
||||||
|
131,
|
||||||
|
176,
|
||||||
|
445,
|
||||||
|
518,
|
||||||
|
586
|
||||||
|
],
|
||||||
|
"119": [
|
||||||
|
210,
|
||||||
|
103,
|
||||||
|
457,
|
||||||
|
478,
|
||||||
|
492
|
||||||
|
],
|
||||||
|
"120": [
|
||||||
|
140,
|
||||||
|
166,
|
||||||
|
567,
|
||||||
|
433,
|
||||||
|
541
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// Schoute's partition via https://arxiv.org/abs/1010.4353
|
// Schoute's partition via https://arxiv.org/abs/1010.4353
|
||||||
|
|
||||||
export const PARTITION600 = {
|
export const PARTITION600 = {
|
||||||
|
|||||||
@ -14,6 +14,7 @@ export const get_colours = (basis) => {
|
|||||||
const hsl = colours.map((c) => Color("#" + c).hsl());
|
const hsl = colours.map((c) => Color("#" + c).hsl());
|
||||||
const resaturated = hsl.map((hslc) => hslc.saturationl(saturation).rgbNumber());
|
const resaturated = hsl.map((hslc) => hslc.saturationl(saturation).rgbNumber());
|
||||||
resaturated.unshift(basis);
|
resaturated.unshift(basis);
|
||||||
|
console.log(resaturated);
|
||||||
return resaturated;
|
return resaturated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1
explore_120
Normal file
1
explore_120
Normal file
@ -0,0 +1 @@
|
|||||||
|
|
||||||
492
explore_120cell.js
Normal file
492
explore_120cell.js
Normal file
@ -0,0 +1,492 @@
|
|||||||
|
|
||||||
|
import * as POLYTOPES from './polytopes.js';
|
||||||
|
|
||||||
|
// exploring more inscriptions of the 120-cell
|
||||||
|
|
||||||
|
|
||||||
|
function choice(a) {
|
||||||
|
const r = Math.floor(Math.random() * a.length);
|
||||||
|
return a[r];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function nodes_links(links, nodeid) {
|
||||||
|
return links.filter((l) => l.source === nodeid || l.target === nodeid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function linked(links, n1, n2) {
|
||||||
|
const ls = nodes_links(nodes_links(links, n1), n2);
|
||||||
|
if( ls.length ) {
|
||||||
|
return ls[0]
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function fingerprint(ids) {
|
||||||
|
const sids = [...ids];
|
||||||
|
sids.sort();
|
||||||
|
return sids.join(',');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function dist(n1, n2) {
|
||||||
|
return Math.sqrt((n1.x - n2.x) ** 2 + (n1.y - n2.y) ** 2 + (n1.z - n2.z) ** 2 + (n1.w - n2.w) ** 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function make_120cell() {
|
||||||
|
const nodes = POLYTOPES.make_120cell_vertices();
|
||||||
|
const links = POLYTOPES.auto_detect_edges(nodes, 4);
|
||||||
|
return {
|
||||||
|
nodes: nodes,
|
||||||
|
links: links
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function round_dist(raw) {
|
||||||
|
return Math.floor(raw * 100000) / 100000;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function distance_groups(cell120) {
|
||||||
|
// get list of other nodes by distance
|
||||||
|
// sort them and dump them out
|
||||||
|
const dists = {};
|
||||||
|
|
||||||
|
cell120.nodes.map((n) => {
|
||||||
|
const draw = dist(cell120.nodes[0], n);
|
||||||
|
const dtrunc = round_dist(draw);
|
||||||
|
if( !(dtrunc in dists) ) {
|
||||||
|
dists[dtrunc] = [];
|
||||||
|
}
|
||||||
|
dists[dtrunc].push(n);
|
||||||
|
});
|
||||||
|
return dists;
|
||||||
|
}
|
||||||
|
|
||||||
|
function distance_group(cell120, n0, chord) {
|
||||||
|
const nodes = []
|
||||||
|
cell120.nodes.map((n) => {
|
||||||
|
const d = round_dist(dist(n0, n));
|
||||||
|
if( d == chord ) {
|
||||||
|
nodes.push(n);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// filter and return those whose chord is also the same
|
||||||
|
const equidistant = [];
|
||||||
|
for( const n1 of nodes ) {
|
||||||
|
for( const n2 of nodes ) {
|
||||||
|
if( n2.id > n1.id ) {
|
||||||
|
if( round_dist(dist(n1, n2)) == chord ) {
|
||||||
|
equidistant.push([n1, n2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return equidistant;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function chord_survey() {
|
||||||
|
const cell120 = POLYTOPES.cell120_inscribed();
|
||||||
|
|
||||||
|
const dgroups = distance_groups(cell120);
|
||||||
|
|
||||||
|
const dists = Object.keys(dgroups);
|
||||||
|
|
||||||
|
dists.sort();
|
||||||
|
|
||||||
|
for( const d of dists ) {
|
||||||
|
const g0 = dgroups[d][0];
|
||||||
|
dgroups[d].map((g) => {
|
||||||
|
console.log(`${g0.id}-${g.id}: ${round_dist(dist(g0, g))}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function overlap(c1, c2) {
|
||||||
|
for( const l in c1 ) {
|
||||||
|
if( c1[l] === c2[l] ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function c5match(c1, c2) {
|
||||||
|
for( const l in c1 ) {
|
||||||
|
if( c1[l] != c2[l] ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function gather_5cells(cell120) {
|
||||||
|
const CHORD5 = round_dist(Math.sqrt(2.5));
|
||||||
|
const bins = [];
|
||||||
|
const all = [];
|
||||||
|
cell120.nodes.filter((n) => n.label === 1).map((n) => {
|
||||||
|
const cells = [ ];
|
||||||
|
const g = distance_group(cell120, n, CHORD5);
|
||||||
|
for( const pair of g ) {
|
||||||
|
let seen = false;
|
||||||
|
for( const cell of cells ) {
|
||||||
|
const c = Object.values(cell);
|
||||||
|
if( c.includes(pair[0].id) || c.includes(pair[1].id) ) {
|
||||||
|
if( !c.includes(pair[0].id) ) {
|
||||||
|
cell[pair[0].label] = pair[0].id;
|
||||||
|
}
|
||||||
|
if( !c.includes(pair[1].id) ) {
|
||||||
|
cell[pair[1].label] = pair[1].id;
|
||||||
|
}
|
||||||
|
seen = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( !seen ) {
|
||||||
|
const cell = {};
|
||||||
|
cell[1]= n.id;
|
||||||
|
cell[pair[0].label] = pair[0].id;
|
||||||
|
cell[pair[1].label] = pair[1].id;
|
||||||
|
cells.push(cell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
all.push(...cells);
|
||||||
|
});
|
||||||
|
return all;
|
||||||
|
}
|
||||||
|
|
||||||
|
function audit_5cells(cells) {
|
||||||
|
// this verifies that for each label (a 600-cell set), each of its
|
||||||
|
// vertices is in exactly 7 5-cells. It checks out.
|
||||||
|
|
||||||
|
['1','2','3','4','5'].map((l) => {
|
||||||
|
const sets = {};
|
||||||
|
for( const cell of cells ) {
|
||||||
|
const lv = cell[l];
|
||||||
|
if( !(lv in sets) ) {
|
||||||
|
sets[lv] = [];
|
||||||
|
}
|
||||||
|
sets[lv].push(cell);
|
||||||
|
}
|
||||||
|
for( const lv in sets ) {
|
||||||
|
const ok = ( sets[lv].length === 7 ) ? 'ok' : 'miss';
|
||||||
|
console.log(`${l},${lv},${sets[lv].length},${ok}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function try_120_5_cells_fails(cell120, cells, l) {
|
||||||
|
// iterate over every vertex in the 600-cell defined by label l,
|
||||||
|
// get all 7 5-cells including that vertex, and add them if they are
|
||||||
|
// disjoint with what we already have
|
||||||
|
|
||||||
|
// this always runs out of disjoint nodes early
|
||||||
|
|
||||||
|
const vertices = cell120.nodes.filter((n) => n.label === l);
|
||||||
|
|
||||||
|
const cellset = [];
|
||||||
|
for( const v of vertices ) {
|
||||||
|
console.log(`Vertex ${v.id}`);
|
||||||
|
const vcells = cells.filter((c) => c[l] === v.id);
|
||||||
|
const overlap_any = (cs, c) => {
|
||||||
|
for( const seen of cs ) {
|
||||||
|
if( overlap(seen, c) ) {
|
||||||
|
console.log("overlap");
|
||||||
|
console.log(c);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const disjoint = vcells.filter((c) => ! overlap_any(cellset, c));
|
||||||
|
console.log(`Found ${disjoint.length} disjoint cells`);
|
||||||
|
if( disjoint.length > 0 ) {
|
||||||
|
cellset.push(choice(disjoint));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`Found total of ${cellset.length} disjoint cells`);
|
||||||
|
//console.log(cellset);
|
||||||
|
}
|
||||||
|
|
||||||
|
function overlap_any(cs, c) {
|
||||||
|
for( const seen of cs ) {
|
||||||
|
if( overlap(seen, c) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function explore_disjoint(cell120, all5, l) {
|
||||||
|
const a = all5[0];
|
||||||
|
|
||||||
|
const overlaps = all5.filter((c) => overlap(c, a));
|
||||||
|
|
||||||
|
console.log(a);
|
||||||
|
|
||||||
|
console.log(overlaps.length);
|
||||||
|
console.log(overlaps);
|
||||||
|
}
|
||||||
|
|
||||||
|
// select a five-cell from a starting vertex v
|
||||||
|
// find a neighbor of v vn on its 600 cell, find all of the 5-cells which include
|
||||||
|
// vn. Then see if we can find any from that set which are similiar neighbours to
|
||||||
|
// the other four vertices in the first 5-cell
|
||||||
|
|
||||||
|
// the idea is that the 600-cells are a guide to finding the right subset of
|
||||||
|
// 5-cells
|
||||||
|
|
||||||
|
function neighbours600(cell120, vid) {
|
||||||
|
const v = cell120.nodes.filter((node) => node.id === vid)[0];
|
||||||
|
const label = v.label;
|
||||||
|
const links = cell120.links.filter((l) => {
|
||||||
|
return l.label === v.label && (l.source === v.id || l.target == v.id );
|
||||||
|
});
|
||||||
|
const nodes = links.map((l) => {
|
||||||
|
if( l.source === v.id ) {
|
||||||
|
return l.target;
|
||||||
|
} else {
|
||||||
|
return l.source;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
function cell120node(cell120, nid) {
|
||||||
|
return cell120.nodes.filter((n) => n.id === nid)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
function node_dist(cell120, aid, bid) {
|
||||||
|
const a = cell120node(cell120, aid);
|
||||||
|
const b = cell120node(cell120, bid);
|
||||||
|
return dist(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
function print_row(v1, v2, p, v5) {
|
||||||
|
console.log(`${v1.id},${v2.id},${p},${v5[1]},${v5[2]},${v5[3]},${v5[4]},${v5[5]}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// for a pair of vertices which are on the same inscribed 600 cell,
|
||||||
|
// this returns all 7 pairs of 5-cells which contain v1 and v2 and
|
||||||
|
// which are also evenly spaced (ie every pair of vertices on the
|
||||||
|
// same 600-cell is one edge apart)
|
||||||
|
|
||||||
|
|
||||||
|
function find_adjoining_5cells(cell120, all5, v1, v2) {
|
||||||
|
const DIST600 = round_dist(node_dist(cell120, v1.id, v2.id));
|
||||||
|
const v15s = all5.filter((c5) => c5[v1.label] === v1.id);
|
||||||
|
const v25s = all5.filter((c5) => c5[v2.label] === v2.id);
|
||||||
|
let p = 0;
|
||||||
|
const c5pairs = [];
|
||||||
|
for( const v5a of v15s ) {
|
||||||
|
for( const v5b of v25s ) {
|
||||||
|
let match = true;
|
||||||
|
const d = {};
|
||||||
|
for( const label in v5a ) {
|
||||||
|
d[label] = round_dist(node_dist(cell120, v5a[label], v5b[label]));
|
||||||
|
if( d[label] != DIST600 ) {
|
||||||
|
match = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( match ) {
|
||||||
|
c5pairs.push([ v5a, v5b ]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c5pairs;
|
||||||
|
}
|
||||||
|
|
||||||
|
function tetras(cell120, v) {
|
||||||
|
// given a vertex v, find all of the 600-cell tetras it's on
|
||||||
|
|
||||||
|
const n600s = neighbours600(cell120, v.id);
|
||||||
|
// need to find all sets of three neighbours which are neighbours: there
|
||||||
|
// should be 20 of these because they're faces of an icosahedron
|
||||||
|
const tetras = new Set;
|
||||||
|
for( const v2id of n600s ) {
|
||||||
|
// find mutual neighbours of the first two
|
||||||
|
const n2600s = neighbours600(cell120, v2id);
|
||||||
|
const mutuals = n2600s.filter((nid) => {
|
||||||
|
return nid != v2id && nid != v.id && n600s.includes(nid)
|
||||||
|
});
|
||||||
|
for( const nm of mutuals ) {
|
||||||
|
const nnms = neighbours600(cell120, nm);
|
||||||
|
const mutuals2 = nnms.filter((nid) => {
|
||||||
|
return nid != nm && nid != v2id && nid != v.id && mutuals.includes(nid)
|
||||||
|
});
|
||||||
|
for( const m2 of mutuals2 ) {
|
||||||
|
const t = [ v.id, v2id, nm, m2 ];
|
||||||
|
t.sort((a, b) => a - b);
|
||||||
|
const tstr = t.join(',');
|
||||||
|
tetras.add(tstr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const tarray = [];
|
||||||
|
for( const t of tetras ) {
|
||||||
|
const ta = t.split(',').map((v) => Number(v));
|
||||||
|
tarray.push(ta);
|
||||||
|
}
|
||||||
|
return tarray;
|
||||||
|
}
|
||||||
|
|
||||||
|
function vertices(hedra) {
|
||||||
|
const v = new Set;
|
||||||
|
for ( const h of hedra) {
|
||||||
|
for( const p of h ) {
|
||||||
|
v.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Array.from(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
function str5cell(c5) {
|
||||||
|
return ["1","2","3","4","5"].map((l) => String(c5[l]).padStart(3, '0')).join('-');
|
||||||
|
}
|
||||||
|
|
||||||
|
function tetra_sets(cell120, all5, tetra) {
|
||||||
|
// given a tetrahedron on a 600-cell, find the sets of adjacent 5-cells on
|
||||||
|
// all of the pairs
|
||||||
|
// this is ass-backwards. Need to find tetras on the other 4 vertices of a 5-cell
|
||||||
|
|
||||||
|
const vs = tetra.map((tid) => cell120node(cell120, tid));
|
||||||
|
const pairs = [[0,1], [0,2], [0, 3], [1, 2], [1, 3], [2, 3]];
|
||||||
|
for( const p of pairs ) {
|
||||||
|
const v1 = vs[p[0]];
|
||||||
|
const v2 = vs[p[1]];
|
||||||
|
const c5pairs = find_adjoining_5cells(cell120, all5, v1, v2);
|
||||||
|
console.log(v1.id, v2.id);
|
||||||
|
console.log(c5pairs.map((p) => str5cell(p[0]) + " " + str5cell(p[1])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cell5_neighbourhoods(cell120, all5, c5) {
|
||||||
|
const neighbours = {}
|
||||||
|
|
||||||
|
for( const l in c5 ) {
|
||||||
|
const v = cell120node(cell120, c5[l]);
|
||||||
|
neighbours[l] = vertices(tetras(cell120, v));
|
||||||
|
}
|
||||||
|
|
||||||
|
// now take the set of all 5-cells and filter it to only those whose vertices
|
||||||
|
// are in the neighour sets. On first inspection there are 13?
|
||||||
|
|
||||||
|
const n5cells = all5.filter((c5) => {
|
||||||
|
for( const l in c5 ) {
|
||||||
|
if( ! neighbours[l].includes(c5[l]) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
return n5cells;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function cell5_tetras(cell120, all5, c5) {
|
||||||
|
const nb = cell5_neighbourhoods(cell120, all5, c5);
|
||||||
|
const v1 = cell120node(cell120, c5["1"]);
|
||||||
|
const ts = tetras(cell120, v1);
|
||||||
|
|
||||||
|
const c5s = [];
|
||||||
|
for( const t of ts ) {
|
||||||
|
const nt = nb.filter((n) => {
|
||||||
|
for( const l in n ) {
|
||||||
|
if( t.includes(n[l]) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
});
|
||||||
|
for( const nc5 of nt ) {
|
||||||
|
const exact = c5s.filter((c) => c5match(c, nc5));
|
||||||
|
if( exact.length === 0 ) {
|
||||||
|
const o = c5s.filter((c) => overlap(c, nc5));
|
||||||
|
if( o.length > 0 ) {
|
||||||
|
console.log("Overlap", c5, o);
|
||||||
|
} else {
|
||||||
|
c5s.push(nc5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function coherent_5cells_r(cell120, all5, c5s, c50) {
|
||||||
|
// Find next set of c5s, see if there are any we haven't seen,
|
||||||
|
// recurse into those ones
|
||||||
|
const c5ns = cell5_tetras(cell120, all5, c50);
|
||||||
|
const c5unseen = c5ns.filter((c5) => {
|
||||||
|
const matched = c5s.filter((c5b) => c5match(c5b, c5));
|
||||||
|
return matched.length === 0;
|
||||||
|
});
|
||||||
|
for( const c5u of c5unseen ) {
|
||||||
|
c5s.push(c5u);
|
||||||
|
}
|
||||||
|
for( const c5u of c5unseen ) {
|
||||||
|
coherent_5cells_r(cell120, all5, c5s, c5u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function coherent_5cells(cell120, all5) {
|
||||||
|
// pick a starting point, collect coherent 5_cells, continue till
|
||||||
|
// there aren't any new ones
|
||||||
|
|
||||||
|
const c5set = [];
|
||||||
|
let c5 = all5[0];
|
||||||
|
|
||||||
|
const c5s = [];
|
||||||
|
coherent_5cells_r(cell120, all5, c5s, c5);
|
||||||
|
return c5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const cell120 = POLYTOPES.cell120_inscribed();
|
||||||
|
const all5 = gather_5cells(cell120);
|
||||||
|
|
||||||
|
const c5s = coherent_5cells(cell120, all5);
|
||||||
|
|
||||||
|
const celli = c5s.map((c5) => [ "1", "2", "3", "4", "5" ].map((l) => c5[l]));
|
||||||
|
|
||||||
|
|
||||||
|
// check it because I don't believe it yet
|
||||||
|
|
||||||
|
const vertex_check = {};
|
||||||
|
|
||||||
|
for( const c5 of celli ) {
|
||||||
|
for( const l in c5 ) {
|
||||||
|
const v = c5[l];
|
||||||
|
if( v in vertex_check ) {
|
||||||
|
console.log(`Double count vertex ${v}`);
|
||||||
|
}
|
||||||
|
vertex_check[v] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for( let i = 1; i < 601; i++ ) {
|
||||||
|
if( !vertex_check[i] ) {
|
||||||
|
console.log(`v ${i} missing`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const idict = {};
|
||||||
|
for( let i = 1; i < 121; i++ ) {
|
||||||
|
idict[i] = celli[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(JSON.stringify(idict, null, 2));
|
||||||
@ -62,7 +62,7 @@ class FourDShape extends THREE.Group {
|
|||||||
const s1 = this.link_scale * n1.scale;
|
const s1 = this.link_scale * n1.scale;
|
||||||
const s2 = this.link_scale * n2.scale;
|
const s2 = this.link_scale * n2.scale;
|
||||||
link.object.update(n1, n2, s1, s2);
|
link.object.update(n1, n2, s1, s2);
|
||||||
link.object.visible = (!links_show || link.label in links_show);
|
link.object.visible = (!links_show || links_show.includes(link.label));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ class FourDShape extends THREE.Group {
|
|||||||
this.nodes3[n.id].scale = k * this.foreshortening;
|
this.nodes3[n.id].scale = k * this.foreshortening;
|
||||||
this.nodes3[n.id].object.position.copy(v3);
|
this.nodes3[n.id].object.position.copy(v3);
|
||||||
this.nodes3[n.id].object.scale.copy(s3);
|
this.nodes3[n.id].object.scale.copy(s3);
|
||||||
this.nodes3[n.id].object.visible = ( !nodes_show || n.label in nodes_show );
|
this.nodes3[n.id].object.visible = ( !nodes_show || nodes_show.includes(n.label) );
|
||||||
}
|
}
|
||||||
for( const l of this.links ) {
|
for( const l of this.links ) {
|
||||||
this.updateLink(l, links_show);
|
this.updateLink(l, links_show);
|
||||||
|
|||||||
53
gui.js
53
gui.js
@ -7,6 +7,7 @@ const DEFAULTS = {
|
|||||||
linksize: 1.0,
|
linksize: 1.0,
|
||||||
linkopacity: 0.75,
|
linkopacity: 0.75,
|
||||||
shape: '120-cell',
|
shape: '120-cell',
|
||||||
|
link2opacity: 0.75,
|
||||||
option: 'none',
|
option: 'none',
|
||||||
visibility: 5,
|
visibility: 5,
|
||||||
inscribed: false,
|
inscribed: false,
|
||||||
@ -15,8 +16,8 @@ const DEFAULTS = {
|
|||||||
background: 0xd4d4d4,
|
background: 0xd4d4d4,
|
||||||
hyperplane: 0.93,
|
hyperplane: 0.93,
|
||||||
zoom: 1,
|
zoom: 1,
|
||||||
xRotate: 'YW',
|
xRotate: 'YZ',
|
||||||
yRotate: 'XW',
|
yRotate: 'XZ',
|
||||||
dtheta: 0,
|
dtheta: 0,
|
||||||
damping: false,
|
damping: false,
|
||||||
captions: true,
|
captions: true,
|
||||||
@ -27,9 +28,10 @@ const DEFAULTS = {
|
|||||||
|
|
||||||
class FourDGUI {
|
class FourDGUI {
|
||||||
|
|
||||||
constructor(shapes, changeShape, setColor, setBackground, setNodeOpacity,setLinkOpacity, setVisibility, showDocs) {
|
constructor(funcs) {
|
||||||
|
this.shapes = funcs.shapes;
|
||||||
this.gui = new GUI();
|
this.gui = new GUI();
|
||||||
const SHAPE_NAMES = shapes.map((s) => s.name);
|
const SHAPE_NAMES = this.shapes.map((s) => s.name);
|
||||||
|
|
||||||
this.parseLinkParams();
|
this.parseLinkParams();
|
||||||
const guiObj = this;
|
const guiObj = this;
|
||||||
@ -40,6 +42,7 @@ class FourDGUI {
|
|||||||
inscribe_all: this.link['inscribe_all'],
|
inscribe_all: this.link['inscribe_all'],
|
||||||
linksize: this.link['linksize'],
|
linksize: this.link['linksize'],
|
||||||
linkopacity: this.link['linkopacity'],
|
linkopacity: this.link['linkopacity'],
|
||||||
|
link2opacity: this.link['link2opacity'],
|
||||||
nodesize: this.link['nodesize'],
|
nodesize: this.link['nodesize'],
|
||||||
nodeopacity: this.link['nodeopacity'],
|
nodeopacity: this.link['nodeopacity'],
|
||||||
depth: this.link['depth'],
|
depth: this.link['depth'],
|
||||||
@ -53,39 +56,52 @@ class FourDGUI {
|
|||||||
captions: true,
|
captions: true,
|
||||||
dtheta: this.link['dtheta'],
|
dtheta: this.link['dtheta'],
|
||||||
dpsi: this.link['dpsi'],
|
dpsi: this.link['dpsi'],
|
||||||
"copy link": function () { guiObj.copyUrl() }
|
"copy link": function () { guiObj.copyUrl() },
|
||||||
};
|
};
|
||||||
|
if( funcs.extras ) {
|
||||||
|
for( const label in funcs.extras ) {
|
||||||
|
console.log(label);
|
||||||
|
console.log(funcs.extras[label]);
|
||||||
|
this.params[label] = funcs.extras[label];
|
||||||
|
}
|
||||||
|
}
|
||||||
let options_ctrl;
|
let options_ctrl;
|
||||||
this.gui.add(this.params, 'shape', SHAPE_NAMES).onChange((shape) => {
|
this.gui.add(this.params, 'shape', SHAPE_NAMES).onChange((shape) => {
|
||||||
const options = this.getShapeOptions(shapes, shape);
|
const options = this.getShapeOptions(shape);
|
||||||
options_ctrl = options_ctrl.options(options).onChange((option) => {
|
options_ctrl = options_ctrl.options(options).onChange((option) => {
|
||||||
setVisibility(option)
|
funcs.setVisibility(option)
|
||||||
});
|
});
|
||||||
options_ctrl.setValue(options[0])
|
options_ctrl.setValue(options[0])
|
||||||
changeShape(shape)
|
funcs.changeShape(shape)
|
||||||
});
|
});
|
||||||
const options = this.getShapeOptions(shapes, this.params['shape']);
|
const options = this.getShapeOptions(this.params['shape']);
|
||||||
options_ctrl = this.gui.add(this.params, 'option').options(options).onChange((option) => {
|
options_ctrl = this.gui.add(this.params, 'option').options(options).onChange((option) => {
|
||||||
setVisibility(option)
|
funcs.setVisibility(option)
|
||||||
});
|
});
|
||||||
this.gui.add(this.params, 'hyperplane', 0.5, 1 / 0.8);
|
this.gui.add(this.params, 'hyperplane', 0.5, 1 / 0.8);
|
||||||
this.gui.add(this.params, 'zoom', 0.1, 2.0);
|
this.gui.add(this.params, 'zoom', 0.1, 2.0);
|
||||||
this.gui.add(this.params, 'nodesize', 0, 1.5);
|
this.gui.add(this.params, 'nodesize', 0, 1.5);
|
||||||
this.gui.add(this.params, 'nodeopacity', 0, 1).onChange(setNodeOpacity);
|
this.gui.add(this.params, 'nodeopacity', 0, 1).onChange(funcs.setNodeOpacity);
|
||||||
this.gui.add(this.params, 'linksize', 0, 2);
|
this.gui.add(this.params, 'linksize', 0, 2);
|
||||||
this.gui.add(this.params, 'linkopacity', 0, 1).onChange(setLinkOpacity);
|
console.log(funcs.setLinkOpacity);
|
||||||
this.gui.addColor(this.params, 'color').onChange(setColor);
|
this.gui.add(this.params, 'linkopacity', 0, 1).onChange((v) => funcs.setLinkOpacity(v, true));
|
||||||
this.gui.addColor(this.params, 'background').onChange(setBackground);
|
this.gui.add(this.params, 'link2opacity', 0, 1).onChange((v) => funcs.setLinkOpacity(v, false));
|
||||||
|
this.gui.addColor(this.params, 'color').onChange(funcs.setColor);
|
||||||
|
this.gui.addColor(this.params, 'background').onChange(funcs.setBackground);
|
||||||
this.gui.add(this.params, 'xRotate', [ 'YW', 'YZ', 'ZW' ]);
|
this.gui.add(this.params, 'xRotate', [ 'YW', 'YZ', 'ZW' ]);
|
||||||
this.gui.add(this.params, 'yRotate', [ 'XZ', 'XY', 'XW' ]);
|
this.gui.add(this.params, 'yRotate', [ 'XZ', 'XY', 'XW' ]);
|
||||||
this.gui.add(this.params, 'captions').onChange(showDocs);
|
this.gui.add(this.params, 'captions').onChange(this.showDocs);
|
||||||
this.gui.add(this.params, 'damping');
|
this.gui.add(this.params, 'damping');
|
||||||
this.gui.add(this.params, 'copy link');
|
this.gui.add(this.params, 'copy link');
|
||||||
|
if( funcs.extras ) {
|
||||||
|
for( const label in funcs.extras ) {
|
||||||
|
this.gui.add(this.params, label);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getShapeOptions(shapes, shape) {
|
getShapeOptions(shape) {
|
||||||
const spec = shapes.filter((s) => s.name === shape);
|
const spec = this.shapes.filter((s) => s.name === shape);
|
||||||
if( spec && spec[0].options ) {
|
if( spec && spec[0].options ) {
|
||||||
return spec[0].options.map((o) => o.name);
|
return spec[0].options.map((o) => o.name);
|
||||||
} else {
|
} else {
|
||||||
@ -136,6 +152,7 @@ class FourDGUI {
|
|||||||
this.link['zoom'] = this.numParam('zoom', parseFloat);
|
this.link['zoom'] = this.numParam('zoom', parseFloat);
|
||||||
this.link['linksize'] = this.numParam('linksize', parseFloat);
|
this.link['linksize'] = this.numParam('linksize', parseFloat);
|
||||||
this.link['linkopacity'] = this.numParam('linkopacity', parseFloat);
|
this.link['linkopacity'] = this.numParam('linkopacity', parseFloat);
|
||||||
|
this.link['link2opacity'] = this.numParam('link2opacity', parseFloat);
|
||||||
this.link['nodesize'] = this.numParam('nodesize', parseFloat);
|
this.link['nodesize'] = this.numParam('nodesize', parseFloat);
|
||||||
this.link['nodeopacity'] = this.numParam('nodeopacity', parseFloat);
|
this.link['nodeopacity'] = this.numParam('nodeopacity', parseFloat);
|
||||||
this.link['color'] = this.numParam('color', (s) => guiObj.stringToHex(s));
|
this.link['color'] = this.numParam('color', (s) => guiObj.stringToHex(s));
|
||||||
|
|||||||
@ -36,7 +36,7 @@
|
|||||||
<script type="module" src="/main.js"></script>
|
<script type="module" src="/main.js"></script>
|
||||||
<div id="description"></div>
|
<div id="description"></div>
|
||||||
<div id="release_notes"></div>
|
<div id="release_notes"></div>
|
||||||
<div id="info"><a href="#" id="show_notes">release 1.0</a> |
|
<div id="info"><a href="#" id="show_notes">release 1.1</a> |
|
||||||
|
|
||||||
by <a target="_blank" href="https://mikelynch.org/">Mike Lynch</a> |
|
by <a target="_blank" href="https://mikelynch.org/">Mike Lynch</a> |
|
||||||
<a target="_blank" href="https://git.tilde.town/bombinans/fourdjs">source</a></div>
|
<a target="_blank" href="https://git.tilde.town/bombinans/fourdjs">source</a></div>
|
||||||
|
|||||||
27
main.js
27
main.js
@ -68,6 +68,7 @@ link_ms.map((m) => {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
console.log("link_ms", link_ms);
|
||||||
|
|
||||||
|
|
||||||
const face_ms = [
|
const face_ms = [
|
||||||
@ -168,7 +169,11 @@ function setBackground(c) {
|
|||||||
function setLinkOpacity(o, primary) {
|
function setLinkOpacity(o, primary) {
|
||||||
link_ms.map((lm) => lm.opacity = o);
|
link_ms.map((lm) => lm.opacity = o);
|
||||||
if( shape ) {
|
if( shape ) {
|
||||||
shape.links.map((l) => l.object.material.opacity = o);
|
shape.links.map((l) => {
|
||||||
|
if( (primary && l.label == 0) || (!primary && l.label !== 0) ) {
|
||||||
|
l.object.material.opacity = o
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,6 +191,8 @@ function changeShape() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setVisibility(option_name) {
|
function setVisibility(option_name) {
|
||||||
|
console.log("setVisibility", option_name);
|
||||||
|
console.log(structure.options);
|
||||||
const option = structure.options.filter((o) => o.name === option_name);
|
const option = structure.options.filter((o) => o.name === option_name);
|
||||||
if( option.length ) {
|
if( option.length ) {
|
||||||
node_show = option[0].nodes;
|
node_show = option[0].nodes;
|
||||||
@ -197,14 +204,16 @@ function setVisibility(option_name) {
|
|||||||
|
|
||||||
|
|
||||||
gui = new FourDGUI(
|
gui = new FourDGUI(
|
||||||
STRUCTURES,
|
{
|
||||||
changeShape,
|
shapes: STRUCTURES,
|
||||||
setColors,
|
changeShape: changeShape,
|
||||||
setBackground,
|
setColors: setColors,
|
||||||
setNodeOpacity,
|
setBackground: setBackground,
|
||||||
setLinkOpacity,
|
setNodeOpacity: setNodeOpacity,
|
||||||
setVisibility,
|
setLinkOpacity: setLinkOpacity,
|
||||||
showDocs
|
setVisibility: setVisibility,
|
||||||
|
showDocs: showDocs,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// these are here to pick up colour settings from the URL params
|
// these are here to pick up colour settings from the URL params
|
||||||
|
|||||||
41
polytopes.js
41
polytopes.js
@ -443,6 +443,15 @@ export const cell120_inscribed = () => {
|
|||||||
links.push(...links600);
|
links.push(...links600);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CELL5S = CELLINDEX.CELL120_CELL5.cell5s;
|
||||||
|
|
||||||
|
for( const c5 in CELL5S ) {
|
||||||
|
const nodes5 = nodes.filter((n) => CELL5S[c5].includes(n.id));
|
||||||
|
const links5 = auto_detect_edges(nodes5, 5);
|
||||||
|
links5.map((l) => l.label = 8);
|
||||||
|
links.push(...links5);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: '120-cell',
|
name: '120-cell',
|
||||||
nodes: nodes,
|
nodes: nodes,
|
||||||
@ -450,17 +459,44 @@ export const cell120_inscribed = () => {
|
|||||||
options: [
|
options: [
|
||||||
{ name: "none", links: [ 0 ]},
|
{ name: "none", links: [ 0 ]},
|
||||||
{ name: "one inscribed 600-cell", links: [ 0, 1 ] },
|
{ name: "one inscribed 600-cell", links: [ 0, 1 ] },
|
||||||
{ name: "five inscribed 600-cells", links: [ 0, 1, 2, 3, 4, 5 ] }
|
{ name: "five inscribed 600-cells", links: [ 0, 1, 2, 3, 4, 5 ] },
|
||||||
|
{ name: "120 inscribed 5-cells", links: [ 0, 8 ] },
|
||||||
],
|
],
|
||||||
description: `The 120-cell is the four-dimensional analogue of the
|
description: `The 120-cell is the four-dimensional analogue of the
|
||||||
dodecahedron, and consists of 120 dodecahedra joined at 720 faces,
|
dodecahedron, and consists of 120 dodecahedra joined at 720 faces,
|
||||||
with three dodecahedra around each edge. It is dual to the 600-cell,
|
with three dodecahedra around each edge. It is dual to the 600-cell,
|
||||||
and five 600-cells can be inscribed in its vertices.`,
|
and five 600-cells can be inscribed in its vertices. The converse
|
||||||
|
of this allows 120 5-cells (each of which has one vertex in each
|
||||||
|
of the 5 600-cells) to be inscribed in the 120-cell.`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const cell120_inscribed_cell5 = () => {
|
||||||
|
const nodes = make_120cell_vertices();
|
||||||
|
const links = auto_detect_edges(nodes, 4);
|
||||||
|
|
||||||
|
for( const cstr in CELLINDEX.INDEX120 ) {
|
||||||
|
label_nodes(nodes, CELLINDEX.INDEX120[cstr], Number(cstr));
|
||||||
|
}
|
||||||
|
|
||||||
|
links.map((l) => l.label = 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: '120-cell-5-cell',
|
||||||
|
nodes: nodes,
|
||||||
|
links: links,
|
||||||
|
options: [
|
||||||
|
{ name: "5-cells", links: [ 0, 1, 2, 3, 4, 5, 6, 7, 8 ] },
|
||||||
|
],
|
||||||
|
description: `The 120-cell with one of its 5-cells.`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function partition_coord(i, coords, invert) {
|
function partition_coord(i, coords, invert) {
|
||||||
@ -864,7 +900,6 @@ export const icosahedron = () => {
|
|||||||
|
|
||||||
export const build_all = () => {
|
export const build_all = () => {
|
||||||
return [
|
return [
|
||||||
linkTest(),
|
|
||||||
tetrahedron(),
|
tetrahedron(),
|
||||||
octahedron(),
|
octahedron(),
|
||||||
cube(),
|
cube(),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user