Compare commits
7 Commits
main
...
feature-12
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e59b55f5e | ||
|
|
303a2971fe | ||
|
|
5922a5df60 | ||
|
|
78b79503f9 | ||
|
|
94568470ca | ||
|
|
6ae5c7938f | ||
|
|
f70438f8c5 |
11
cellindex.js
11
cellindex.js
@ -104,6 +104,17 @@ export const LAYERS120 = {
|
||||
163,219,271,223,167]
|
||||
};
|
||||
|
||||
// just one for now
|
||||
|
||||
export const CELL120_CELL5 = {
|
||||
"1": [ 1, 258, 304, 431, 510 ],
|
||||
"2": [ 1, 260, 302, 427, 506 ],
|
||||
"3": [1, 264, 298, 435, 514],
|
||||
"4": [1, 330, 334, 387, 391],
|
||||
"5": [1, 491, 503, 574, 578],
|
||||
"6": [1, 495, 499, 570, 582 ],
|
||||
};
|
||||
|
||||
// Schoute's partition via https://arxiv.org/abs/1010.4353
|
||||
|
||||
export const PARTITION600 = {
|
||||
|
||||
171
explore_120cell.js
Normal file
171
explore_120cell.js
Normal file
@ -0,0 +1,171 @@
|
||||
|
||||
|
||||
import * as POLYTOPES from './polytopes.js';
|
||||
|
||||
// exploring more inscriptions of the 120-cell
|
||||
|
||||
|
||||
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))}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// how to proceed: start with the 120-cell that has five 600-cells inscribed
|
||||
// in it. Take the 120 nodes from one of those 600-cells, and construct a 5-cell
|
||||
// from each such that all of the vertices are on different 600-cells.
|
||||
|
||||
// collect them and output by label because every 5-cell is on all 5 600-cells
|
||||
|
||||
function overlap(c1, c2) {
|
||||
for( const l in c1 ) {
|
||||
if( c1[l] === c2[l] ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
export function gather_5cells() {
|
||||
const cell120 = POLYTOPES.cell120_inscribed();
|
||||
const CHORD5 = round_dist(Math.sqrt(2.5));
|
||||
const bins = [];
|
||||
cell120.nodes.filter((n) => n.label === 1).map((n) => {
|
||||
const g = distance_group(cell120, n, CHORD5);
|
||||
const cells = [ ];
|
||||
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);
|
||||
}
|
||||
}
|
||||
//console.log(`From ${n.id}`);
|
||||
//console.log(cells);
|
||||
for( const cell of cells ) {
|
||||
let binned = false;
|
||||
for( const bin of bins ) {
|
||||
const overlaps = bin.filter((b) => overlap(b, cell));
|
||||
if( overlaps.length === 0 ) {
|
||||
bin.push(cell);
|
||||
binned = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !binned ) {
|
||||
console.log(`new bin for ${JSON.stringify(cell)}`);
|
||||
bins.push([ cell ]);
|
||||
}
|
||||
}
|
||||
//console.log(bins);
|
||||
})
|
||||
;
|
||||
}
|
||||
|
||||
gather_5cells();
|
||||
11
gui.js
11
gui.js
@ -7,6 +7,7 @@ const DEFAULTS = {
|
||||
linksize: 1.0,
|
||||
linkopacity: 0.75,
|
||||
shape: '120-cell',
|
||||
link2opacity: 0.75,
|
||||
option: 'none',
|
||||
visibility: 5,
|
||||
inscribed: false,
|
||||
@ -15,8 +16,8 @@ const DEFAULTS = {
|
||||
background: 0xd4d4d4,
|
||||
hyperplane: 0.93,
|
||||
zoom: 1,
|
||||
xRotate: 'YW',
|
||||
yRotate: 'XW',
|
||||
xRotate: 'YZ',
|
||||
yRotate: 'XZ',
|
||||
dtheta: 0,
|
||||
damping: false,
|
||||
captions: true,
|
||||
@ -40,6 +41,7 @@ class FourDGUI {
|
||||
inscribe_all: this.link['inscribe_all'],
|
||||
linksize: this.link['linksize'],
|
||||
linkopacity: this.link['linkopacity'],
|
||||
link2opacity: this.link['link2opacity'],
|
||||
nodesize: this.link['nodesize'],
|
||||
nodeopacity: this.link['nodeopacity'],
|
||||
depth: this.link['depth'],
|
||||
@ -73,7 +75,9 @@ class FourDGUI {
|
||||
this.gui.add(this.params, 'nodesize', 0, 1.5);
|
||||
this.gui.add(this.params, 'nodeopacity', 0, 1).onChange(setNodeOpacity);
|
||||
this.gui.add(this.params, 'linksize', 0, 2);
|
||||
this.gui.add(this.params, 'linkopacity', 0, 1).onChange(setLinkOpacity);
|
||||
console.log(setLinkOpacity);
|
||||
this.gui.add(this.params, 'linkopacity', 0, 1).onChange((v) => setLinkOpacity(v, true));
|
||||
this.gui.add(this.params, 'link2opacity', 0, 1).onChange((v) => setLinkOpacity(v, false));
|
||||
this.gui.addColor(this.params, 'color').onChange(setColor);
|
||||
this.gui.addColor(this.params, 'background').onChange(setBackground);
|
||||
this.gui.add(this.params, 'xRotate', [ 'YW', 'YZ', 'ZW' ]);
|
||||
@ -136,6 +140,7 @@ class FourDGUI {
|
||||
this.link['zoom'] = this.numParam('zoom', parseFloat);
|
||||
this.link['linksize'] = this.numParam('linksize', parseFloat);
|
||||
this.link['linkopacity'] = this.numParam('linkopacity', parseFloat);
|
||||
this.link['link2opacity'] = this.numParam('link2opacity', parseFloat);
|
||||
this.link['nodesize'] = this.numParam('nodesize', parseFloat);
|
||||
this.link['nodeopacity'] = this.numParam('nodeopacity', parseFloat);
|
||||
this.link['color'] = this.numParam('color', (s) => guiObj.stringToHex(s));
|
||||
|
||||
7
main.js
7
main.js
@ -69,7 +69,6 @@ link_ms.map((m) => {
|
||||
);
|
||||
|
||||
|
||||
|
||||
const face_ms = [
|
||||
new THREE.MeshStandardMaterial( { color: 0x44ff44 } )
|
||||
];
|
||||
@ -168,7 +167,11 @@ function setBackground(c) {
|
||||
function setLinkOpacity(o, primary) {
|
||||
link_ms.map((lm) => lm.opacity = o);
|
||||
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
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
32
polytopes.js
32
polytopes.js
@ -461,6 +461,36 @@ export const cell120_inscribed = () => {
|
||||
|
||||
|
||||
|
||||
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);
|
||||
|
||||
for( const c5 in CELLINDEX.CELL120_CELL5 ) {
|
||||
const nodes5 = nodes.filter((n) => CELLINDEX.CELL120_CELL5[c5].includes(n.id));
|
||||
console.log(`node5 = ${nodes5}`);
|
||||
const links5 = auto_detect_edges(nodes5, 4);
|
||||
links5.map((l) => l.label = c5);
|
||||
links.push(...links5);
|
||||
}
|
||||
|
||||
return {
|
||||
name: '120-cell-5-cell',
|
||||
nodes: nodes,
|
||||
links: links,
|
||||
options: [
|
||||
{ name: "none", links: [ 0 ]},
|
||||
{ name: "one inscribed 5-cell", links: [ 0, 1 ] },
|
||||
],
|
||||
description: `The 120-cell with one of its 5-cells.`,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function partition_coord(i, coords, invert) {
|
||||
@ -864,7 +894,6 @@ export const icosahedron = () => {
|
||||
|
||||
export const build_all = () => {
|
||||
return [
|
||||
linkTest(),
|
||||
tetrahedron(),
|
||||
octahedron(),
|
||||
cube(),
|
||||
@ -878,6 +907,7 @@ export const build_all = () => {
|
||||
cell600(),
|
||||
cell600_layered(),
|
||||
cell120_inscribed(),
|
||||
cell120_inscribed_cell5(),
|
||||
cell120_layered()
|
||||
];
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user