Compare commits
No commits in common. "0e1d8df7b5a7c02a8061ea5b3caa4902fcf9a498" and "1e59b55f5e7a4257e4fb71a966d264efcac9294b" have entirely different histories.
0e1d8df7b5
...
1e59b55f5e
14
cellindex.js
14
cellindex.js
@ -104,12 +104,16 @@ export const LAYERS120 = {
|
|||||||
163,219,271,223,167]
|
163,219,271,223,167]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// just one for now
|
||||||
|
|
||||||
export const CELL120_CELL5 = {
|
export const CELL120_CELL5 = {
|
||||||
"1": [ 258, 1, 510, 304, 431 ],
|
"1": [ 1, 258, 304, 431, 510 ],
|
||||||
"2": [ 185, 93, 222, 295, 372 ],
|
"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
|
// Schoute's partition via https://arxiv.org/abs/1010.4353
|
||||||
|
|
||||||
|
|||||||
@ -1,24 +1,10 @@
|
|||||||
|
|
||||||
// TODO - try visualising the 5-cells from a vertex on the layered 120-cell
|
|
||||||
// and get an intuition for how they work with the dodecahedral structure
|
|
||||||
|
|
||||||
// Another new approach -
|
|
||||||
// pick a starting 5-cell
|
|
||||||
// look at the neighbours on the 120-cell of all of its 5 vertices
|
|
||||||
// try to find abother 5-cell with these neighbours
|
|
||||||
// if there's only one, add that to the list and keep going
|
|
||||||
// if there's more than one, are they disjoint with each other?
|
|
||||||
|
|
||||||
import * as POLYTOPES from './polytopes.js';
|
import * as POLYTOPES from './polytopes.js';
|
||||||
|
|
||||||
// exploring more inscriptions of the 120-cell
|
// 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) {
|
export function nodes_links(links, nodeid) {
|
||||||
return links.filter((l) => l.source === nodeid || l.target === nodeid);
|
return links.filter((l) => l.source === nodeid || l.target === nodeid);
|
||||||
}
|
}
|
||||||
@ -114,6 +100,11 @@ export function chord_survey() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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) {
|
function overlap(c1, c2) {
|
||||||
for( const l in c1 ) {
|
for( const l in c1 ) {
|
||||||
@ -125,13 +116,13 @@ function overlap(c1, c2) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function gather_5cells(cell120) {
|
export function gather_5cells() {
|
||||||
|
const cell120 = POLYTOPES.cell120_inscribed();
|
||||||
const CHORD5 = round_dist(Math.sqrt(2.5));
|
const CHORD5 = round_dist(Math.sqrt(2.5));
|
||||||
const bins = [];
|
const bins = [];
|
||||||
const all = [];
|
|
||||||
cell120.nodes.filter((n) => n.label === 1).map((n) => {
|
cell120.nodes.filter((n) => n.label === 1).map((n) => {
|
||||||
const cells = [ ];
|
|
||||||
const g = distance_group(cell120, n, CHORD5);
|
const g = distance_group(cell120, n, CHORD5);
|
||||||
|
const cells = [ ];
|
||||||
for( const pair of g ) {
|
for( const pair of g ) {
|
||||||
let seen = false;
|
let seen = false;
|
||||||
for( const cell of cells ) {
|
for( const cell of cells ) {
|
||||||
@ -155,163 +146,26 @@ export function gather_5cells(cell120) {
|
|||||||
cells.push(cell);
|
cells.push(cell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
all.push(...cells);
|
//console.log(`From ${n.id}`);
|
||||||
});
|
//console.log(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 ) {
|
for( const cell of cells ) {
|
||||||
const lv = cell[l];
|
let binned = false;
|
||||||
if( !(lv in sets) ) {
|
for( const bin of bins ) {
|
||||||
sets[lv] = [];
|
const overlaps = bin.filter((b) => overlap(b, cell));
|
||||||
}
|
if( overlaps.length === 0 ) {
|
||||||
sets[lv].push(cell);
|
bin.push(cell);
|
||||||
}
|
binned = true;
|
||||||
for( const lv in sets ) {
|
break;
|
||||||
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;
|
if( !binned ) {
|
||||||
}
|
console.log(`new bin for ${JSON.stringify(cell)}`);
|
||||||
const disjoint = vcells.filter((c) => ! overlap_any(cellset, c));
|
bins.push([ cell ]);
|
||||||
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 follow_600(cell120, all5) {
|
|
||||||
const v = cell120.nodes[0];
|
|
||||||
console.log("Start vertex:");
|
|
||||||
console.log(v);
|
|
||||||
const v5s = all5.filter((c5) => c5[v.label] === v.id);
|
|
||||||
console.log(`Vertex ${v.id} belongs to these 5-cells:`);
|
|
||||||
console.log(v5s);
|
|
||||||
const n600s = neighbours600(cell120, v.id);
|
|
||||||
const n600id = n600s[0];
|
|
||||||
const n600 = cell120node(cell120, n600id);
|
|
||||||
console.log("One 600-cell neighbour:");
|
|
||||||
console.log(n600);
|
|
||||||
const DIST600 = round_dist(node_dist(cell120, v.id, n600id));
|
|
||||||
const nv5s = all5.filter((c5) => c5[v.label] === n600id);
|
|
||||||
console.log(`Vertex ${n600id} belongs to these 5-cells:`);
|
|
||||||
console.log(nv5s);
|
|
||||||
console.log("Distances for each pair of 5-cells from the two sets:");
|
|
||||||
for( const v5a of v5s ) {
|
|
||||||
for( const v5b of nv5s ) {
|
|
||||||
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 ) {
|
|
||||||
console.log("--- pair ---");
|
|
||||||
console.log(v5a);
|
|
||||||
console.log(v5b);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
//console.log(bins);
|
||||||
|
})
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gather_5cells();
|
||||||
|
|
||||||
|
|
||||||
const cell120 = POLYTOPES.cell120_inscribed();
|
|
||||||
const all5 = gather_5cells(cell120);
|
|
||||||
|
|
||||||
follow_600(cell120, all5);
|
|
||||||
|
|
||||||
|
|||||||
48
gui.js
48
gui.js
@ -28,10 +28,9 @@ const DEFAULTS = {
|
|||||||
|
|
||||||
class FourDGUI {
|
class FourDGUI {
|
||||||
|
|
||||||
constructor(funcs) {
|
constructor(shapes, changeShape, setColor, setBackground, setNodeOpacity,setLinkOpacity, setVisibility, showDocs) {
|
||||||
this.shapes = funcs.shapes;
|
|
||||||
this.gui = new GUI();
|
this.gui = new GUI();
|
||||||
const SHAPE_NAMES = this.shapes.map((s) => s.name);
|
const SHAPE_NAMES = shapes.map((s) => s.name);
|
||||||
|
|
||||||
this.parseLinkParams();
|
this.parseLinkParams();
|
||||||
const guiObj = this;
|
const guiObj = this;
|
||||||
@ -56,52 +55,41 @@ 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(shape);
|
const options = this.getShapeOptions(shapes, shape);
|
||||||
options_ctrl = options_ctrl.options(options).onChange((option) => {
|
options_ctrl = options_ctrl.options(options).onChange((option) => {
|
||||||
funcs.setVisibility(option)
|
setVisibility(option)
|
||||||
});
|
});
|
||||||
options_ctrl.setValue(options[0])
|
options_ctrl.setValue(options[0])
|
||||||
funcs.changeShape(shape)
|
changeShape(shape)
|
||||||
});
|
});
|
||||||
const options = this.getShapeOptions(this.params['shape']);
|
const options = this.getShapeOptions(shapes, 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) => {
|
||||||
funcs.setVisibility(option)
|
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(funcs.setNodeOpacity);
|
this.gui.add(this.params, 'nodeopacity', 0, 1).onChange(setNodeOpacity);
|
||||||
this.gui.add(this.params, 'linksize', 0, 2);
|
this.gui.add(this.params, 'linksize', 0, 2);
|
||||||
console.log(funcs.setLinkOpacity);
|
console.log(setLinkOpacity);
|
||||||
this.gui.add(this.params, 'linkopacity', 0, 1).onChange((v) => funcs.setLinkOpacity(v, true));
|
this.gui.add(this.params, 'linkopacity', 0, 1).onChange((v) => setLinkOpacity(v, true));
|
||||||
this.gui.add(this.params, 'link2opacity', 0, 1).onChange((v) => funcs.setLinkOpacity(v, false));
|
this.gui.add(this.params, 'link2opacity', 0, 1).onChange((v) => setLinkOpacity(v, false));
|
||||||
this.gui.addColor(this.params, 'color').onChange(funcs.setColor);
|
this.gui.addColor(this.params, 'color').onChange(setColor);
|
||||||
this.gui.addColor(this.params, 'background').onChange(funcs.setBackground);
|
this.gui.addColor(this.params, 'background').onChange(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(this.showDocs);
|
this.gui.add(this.params, 'captions').onChange(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(shape) {
|
getShapeOptions(shapes, shape) {
|
||||||
const spec = this.shapes.filter((s) => s.name === shape);
|
const spec = 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 {
|
||||||
|
|||||||
22
main.js
22
main.js
@ -200,20 +200,14 @@ function setVisibility(option_name) {
|
|||||||
|
|
||||||
|
|
||||||
gui = new FourDGUI(
|
gui = new FourDGUI(
|
||||||
{
|
STRUCTURES,
|
||||||
shapes: STRUCTURES,
|
changeShape,
|
||||||
changeShape: changeShape,
|
setColors,
|
||||||
setColors: setColors,
|
setBackground,
|
||||||
setBackground: setBackground,
|
setNodeOpacity,
|
||||||
setNodeOpacity: setNodeOpacity,
|
setLinkOpacity,
|
||||||
setLinkOpacity: setLinkOpacity,
|
setVisibility,
|
||||||
setVisibility: setVisibility,
|
showDocs
|
||||||
showDocs: showDocs,
|
|
||||||
extras: {
|
|
||||||
"Show an alert": function() { alert("hi there") },
|
|
||||||
"Show a different one": function() { alert('yowza')},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// these are here to pick up colour settings from the URL params
|
// these are here to pick up colour settings from the URL params
|
||||||
|
|||||||
19
polytopes.js
19
polytopes.js
@ -463,27 +463,19 @@ export const cell120_inscribed = () => {
|
|||||||
|
|
||||||
export const cell120_inscribed_cell5 = () => {
|
export const cell120_inscribed_cell5 = () => {
|
||||||
const nodes = make_120cell_vertices();
|
const nodes = make_120cell_vertices();
|
||||||
//const links = auto_detect_edges(nodes, 4);
|
const links = auto_detect_edges(nodes, 4);
|
||||||
|
|
||||||
for( const cstr in CELLINDEX.INDEX120 ) {
|
for( const cstr in CELLINDEX.INDEX120 ) {
|
||||||
label_nodes(nodes, CELLINDEX.INDEX120[cstr], Number(cstr));
|
label_nodes(nodes, CELLINDEX.INDEX120[cstr], Number(cstr));
|
||||||
}
|
}
|
||||||
|
|
||||||
//links.map((l) => l.label = 0);
|
links.map((l) => l.label = 0);
|
||||||
|
|
||||||
const links = [];
|
|
||||||
|
|
||||||
for( const p of [ 1, 2 ]) {
|
|
||||||
const nodes600 = nodes.filter((n) => n.label === p);
|
|
||||||
const links600 = auto_detect_edges(nodes600, 12);
|
|
||||||
links600.map((l) => l.label = p);
|
|
||||||
links.push(...links600);
|
|
||||||
}
|
|
||||||
|
|
||||||
for( const c5 in CELLINDEX.CELL120_CELL5 ) {
|
for( const c5 in CELLINDEX.CELL120_CELL5 ) {
|
||||||
const nodes5 = nodes.filter((n) => CELLINDEX.CELL120_CELL5[c5].includes(n.id));
|
const nodes5 = nodes.filter((n) => CELLINDEX.CELL120_CELL5[c5].includes(n.id));
|
||||||
|
console.log(`node5 = ${nodes5}`);
|
||||||
const links5 = auto_detect_edges(nodes5, 4);
|
const links5 = auto_detect_edges(nodes5, 4);
|
||||||
links5.map((l) => l.label = 0);
|
links5.map((l) => l.label = c5);
|
||||||
links.push(...links5);
|
links.push(...links5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,7 +484,8 @@ export const cell120_inscribed_cell5 = () => {
|
|||||||
nodes: nodes,
|
nodes: nodes,
|
||||||
links: links,
|
links: links,
|
||||||
options: [
|
options: [
|
||||||
{ name: "5-cells", links: [ 0, 1, 2, 3, 4, 5, 6 ] },
|
{ name: "none", links: [ 0 ]},
|
||||||
|
{ name: "one inscribed 5-cell", links: [ 0, 1 ] },
|
||||||
],
|
],
|
||||||
description: `The 120-cell with one of its 5-cells.`,
|
description: `The 120-cell with one of its 5-cells.`,
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user