Refactored the gui defaults and added a 120-cell with one inscribed

600-cell
experiments-120-cell
Mike Lynch 2023-09-02 17:11:08 +10:00
parent 41d8f7ed92
commit 62ae3486d8
4 changed files with 111 additions and 59 deletions

78
gui.js
View File

@ -1,41 +1,53 @@
import { GUI } from 'lil-gui'; import { GUI } from 'lil-gui';
const DEFAULT_SHAPE = '120-cell';
const DEFAULT_COLOR = 0x3293a9; const DEFAULTS = {
const DEFAULT_BG = 0x808080; thickness: 0.25,
nodesize: 1.25,
linkopacity: 0.5,
shape: '120-cell',
color: 0x3293a9,
background: 0xd4d4d4,
hyperplane: 2,
xRotate: 'YW',
yRotate: 'XZ',
dtheta: 0,
dpsi: 0,
}
class FourDGUI { class FourDGUI {
constructor(createShape, setColor, setBackground) { constructor(createShape, setColor, setBackground, setLinkOpacity) {
this.gui = new GUI(); this.gui = new GUI();
this.parseLinkParams(); this.parseLinkParams();
const guiObj = this; const guiObj = this;
console.log(this.link);
this.params = { this.params = {
shape: this.link['shape'] || DEFAULT_SHAPE, shape: this.link['shape'],
thickness: this.link['thickness'] || 1, thickness: this.link['thickness'],
nodesize: this.link['nodesize'] || 2, linkopacity: this.link['linkopacity'],
color: this.link['color'] || DEFAULT_COLOR, nodesize: this.link['nodesize'],
background: this.link['background'] || DEFAULT_BG, color: this.link['color'],
hyperplane: this.link['hyperplane'] || 2, background: this.link['background'],
xRotate: this.link['xRotate'] || 'YW', hyperplane: this.link['hyperplane'],
yRotate: this.link['yRotate'] || 'XZ', xRotate: this.link['xRotate'],
yRotate: this.link['yRotate'],
damping: false, damping: false,
dtheta: this.link['dtheta'] || 0, dtheta: this.link['dtheta'],
dpsi: this.link['dpsi'] || 0, dpsi: this.link['dpsi'],
"copy link": function () { guiObj.copyUrl() } "copy link": function () { guiObj.copyUrl() }
}; };
this.gui.add(this.params, 'shape', this.gui.add(this.params, 'shape',
[ '5-cell', '16-cell', 'tesseract', '24-cell', '600-cell', '120-cell' ] [ '5-cell', '16-cell', 'tesseract', '24-cell', '600-cell', '120-cell', '120-cell-inscribed' ]
).onChange(createShape) ).onChange(createShape)
this.gui.add(this.params, 'hyperplane', 1.5, 3); this.gui.add(this.params, 'hyperplane', 1.5, 2.25);
this.gui.add(this.params, 'thickness', 0.1, 4); this.gui.add(this.params, 'thickness', 0.1, 2);
this.gui.add(this.params, 'nodesize', 0, 5); this.gui.add(this.params, 'linkopacity', 0, 1).onChange(setLinkOpacity);
this.gui.add(this.params, 'nodesize', 0.1, 4);
this.gui.addColor(this.params, 'color').onChange(setColor); this.gui.addColor(this.params, 'color').onChange(setColor);
this.gui.addColor(this.params, 'background').onChange(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' ]);
@ -46,7 +58,7 @@ class FourDGUI {
} }
numParam(param, parser, dft) { numParam(param, parser) {
const value = this.urlParams.get(param); const value = this.urlParams.get(param);
if( value ) { if( value ) {
const n = parser(value); const n = parser(value);
@ -54,7 +66,7 @@ class FourDGUI {
return n; return n;
} }
} }
return dft; return DEFAULTS[param];
} }
stringToHex(cstr) { stringToHex(cstr) {
@ -76,21 +88,19 @@ class FourDGUI {
const value = this.urlParams.get(param); const value = this.urlParams.get(param);
if( value ) { if( value ) {
this.link[param] = value; this.link[param] = value;
} else {
this.link[param] = DEFAULTS[param];
} }
} }
const guiObj = this; const guiObj = this;
this.link['hyperplane'] = this.numParam('hyperplane', parseFloat, 2); this.link['hyperplane'] = this.numParam('hyperplane', parseFloat);
this.link['thickness'] = this.numParam('thickness', parseFloat, 1); this.link['thickness'] = this.numParam('thickness', parseFloat);
this.link['nodesize'] = this.numParam('nodesize', parseFloat, 1); this.link['linkopacity'] = this.numParam('linkopacity', parseFloat);
this.link['color'] = this.numParam( this.link['nodesize'] = this.numParam('nodesize', parseFloat);
'color', (s) => guiObj.stringToHex(s), DEFAULT_COLOR this.link['color'] = this.numParam('color', (s) => guiObj.stringToHex(s));
); this.link['background'] = this.numParam('background', (s) => guiObj.stringToHex(s));
this.link['background'] = this.numParam( this.link['dpsi'] = this.numParam('dpsi', parseFloat);
'background', (s) => guiObj.stringToHex(s), DEFAULT_BG this.link['dtheta'] = this.numParam('dtheta', parseFloat);
);
this.link['dpsi'] = this.numParam('dpsi', parseFloat, 0);
this.link['dtheta'] = this.numParam('dtheta', parseFloat, 0);
} }
@ -151,4 +161,4 @@ class FourDGUI {
} }
export { FourDGUI }; export { FourDGUI, DEFAULTS };

31
main.js
View File

@ -4,7 +4,7 @@ import * as THREE from 'three';
import * as POLYTOPES from './polytopes.js'; import * as POLYTOPES from './polytopes.js';
import { rotfn } from './rotation.js'; import { rotfn } from './rotation.js';
import { FourDGUI } from './gui.js'; import { FourDGUI, DEFAULTS } from './gui.js';
import { FourDShape } from './fourDShape.js'; import { FourDShape } from './fourDShape.js';
import { get_colours } from './colours.js'; import { get_colours } from './colours.js';
@ -31,9 +31,9 @@ document.body.appendChild( renderer.domElement );
// set up colours and materials for gui callbacks // set up colours and materials for gui callbacks
scene.background = new THREE.Color(0x808080); scene.background = new THREE.Color(DEFAULTS.background);
const material = new THREE.MeshStandardMaterial({ color: 0x3293a9 }); const material = new THREE.MeshStandardMaterial({ color: DEFAULTS.color });
const node_colours = get_colours(0x3293a9); const node_colours = get_colours(DEFAULTS.color);
material.transparent = true; material.transparent = true;
@ -41,13 +41,13 @@ material.opacity = 0.5;
const node_ms = node_colours.map((c) => new THREE.MeshStandardMaterial({color: c})); const node_ms = node_colours.map((c) => new THREE.MeshStandardMaterial({color: c}));
const link_ms = node_colours.map((c) => new THREE.MeshStandardMaterial({color: c}));
node_ms[0].transparent = true; link_ms.map((m) => {
node_ms[0].opacity = 0.0; m.transparent = true;
m.opacity = 0.5;
}
const link_ms = [ material ]; )
const face_ms = [ const face_ms = [
new THREE.MeshLambertMaterial( { color: 0x44ff44 } ) new THREE.MeshLambertMaterial( { color: 0x44ff44 } )
@ -65,6 +65,7 @@ const STRUCTURES = {
'tesseract': POLYTOPES.tesseract(), 'tesseract': POLYTOPES.tesseract(),
'24-cell': POLYTOPES.cell24(), '24-cell': POLYTOPES.cell24(),
'120-cell': POLYTOPES.cell120(), '120-cell': POLYTOPES.cell120(),
'120-cell-inscribed': POLYTOPES.cell120_inscribed(),
'600-cell': POLYTOPES.cell600() '600-cell': POLYTOPES.cell600()
}; };
@ -87,6 +88,7 @@ function setColors(c) {
const nc = get_colours(c); const nc = get_colours(c);
for( let i = 0; i < node_ms.length; i++ ) { for( let i = 0; i < node_ms.length; i++ ) {
node_ms[i].color = new THREE.Color(nc[i]); node_ms[i].color = new THREE.Color(nc[i]);
link_ms[i].color = new THREE.Color(nc[i]);
} }
material.color = new THREE.Color(c); material.color = new THREE.Color(c);
} }
@ -95,8 +97,13 @@ function setBackground(c) {
scene.background = new THREE.Color(c) scene.background = new THREE.Color(c)
} }
function setLinkOpacity(o) {
for( const lm of link_ms ) {
lm.opacity = o;
}
}
const gui = new FourDGUI(createShape, setColors, setBackground); const gui = new FourDGUI(createShape, setColors, setBackground, setLinkOpacity);
// these are here to pick up colour settings from the URL params // these are here to pick up colour settings from the URL params
setColors(gui.params.color); setColors(gui.params.color);
@ -159,7 +166,7 @@ function animate() {
]; ];
shape.hyperplane = gui.params.hyperplane; shape.hyperplane = gui.params.hyperplane;
shape.link_scale = gui.params.thickness; shape.link_scale = gui.params.thickness;
shape.node_scale = gui.params.thickness * (gui.params.nodesize + 1); shape.node_scale = gui.params.nodesize;
shape.render3(rotations); shape.render3(rotations);
renderer.render( scene, camera ); renderer.render( scene, camera );

View File

@ -320,18 +320,6 @@ function basic_auto_label_120cell(nodes, links) {
} }
} }
// label_faces_120cell(nodes, faces, [
// 1, 2, 4, 169, 626,
// 145, 149, 553, 173, 171,
// 147, 554
// ], 2);
// label_faces_120cell(nodes, faces, [
// 1, 5, 3, 193, 641,
// 217, 221, 565, 197, 195,
// 219, 566
// ], 3);
} }
function label_120cell(nodes) { function label_120cell(nodes) {
@ -368,6 +356,34 @@ export const cell120 = () => {
} }
} }
export const cell120_inscribed = () => {
const nodes = make_120cell_vertices();
const links = auto_detect_edges(nodes, 4);
label_120cell(nodes);
const all_links = links;
all_links.map((l) => l.label = 0);
for( const p of [ 5 ]) {
const nodes600 = nodes.filter((n) => n.label === p);
const links600 = auto_detect_edges(nodes600, 12);
links600.map((l) => l.label = p);
all_links.push(...links600);
}
return {
nodes: nodes,
links: all_links,
geometry: {
node_size: 0.02,
link_size: 0.02
},
}
}
// Schoute's partition via https://arxiv.org/abs/1010.4353 // Schoute's partition via https://arxiv.org/abs/1010.4353
const partition600 = { const partition600 = {

View File

@ -896,17 +896,36 @@ function meridian_label_120cell(nodes) {
} }
function check_120cell_nodes(nodes) {
nodes.map((n) => {
const vs = find_adjacent_labels(nodes, links, n.id);
vs.push(n.label);
console.log(`Node ${n.id} and neighbours ${vs}`);
const fp = vs.sort().join(',');
if( fp !== "1,2,3,4,5" ) {
console.log(`Label error ${n.id} ${fp}`)
}
});
}
const nodes = make_120cell_vertices(); const nodes = make_120cell_vertices();
const links = auto_detect_edges(nodes, 4); const links = auto_detect_edges(nodes, 4);
const faces = auto_120cell_faces(links); const faces = auto_120cell_faces(links);
console.log("Calculating 120-cell colours")
const a2 = arctic_two(nodes, links, faces, faces[0], 341) const a2 = arctic_two(nodes, links, faces, faces[0], 341)
console.log(`got ${a2.dodecahedra.length}`); console.log(`got ${a2.dodecahedra.length}`);
console.log(JSON.stringify(a2.labels)); const labels = a2.labels;
console.log("labelling nodes");
for( const cstr in labels ) {
label_nodes(nodes, labels[cstr], Number(cstr));
}