diff --git a/fourDShape.js b/fourDShape.js index ff7b660..dc58168 100644 --- a/fourDShape.js +++ b/fourDShape.js @@ -20,7 +20,8 @@ class FourDShape extends THREE.Group { this.node_scale = 1; this.link_scale = 1; this.hyperplane = HYPERPLANE; - this.label_visible = () => true; + this.node_f = () => true; + this.link_f = () => true; this.initShapes(); } @@ -74,7 +75,7 @@ class FourDShape extends THREE.Group { link.object.children[0].rotation.x = Math.PI / 2.0; const l1 = this.nodes3[link.source].label; const l2 = this.nodes3[link.target].label; - link.object.visible = this.label_visible(l1) && this.label_visible(l2); + link.object.visible = this.link_f(link.label); } @@ -134,19 +135,18 @@ class FourDShape extends THREE.Group { } - render3(rotations, visibility) { - this.label_visible = visibility; + render3(rotations, node_f, link_f) { this.scalev3 = new THREE.Vector3(this.node_scale, this.node_scale, this.node_scale); for( const n of this.nodes4 ) { const v3 = this.fourDtoV3(n.x, n.y, n.z, n.w, rotations); this.nodes3[n.id].v3 = v3; this.nodes3[n.id].object.position.copy(v3); this.nodes3[n.id].object.scale.copy(this.scalev3); - this.nodes3[n.id].object.visible = this.label_visible(n.label); + this.nodes3[n.id].object.visible = node_f(n.label); } - + this.link_f = link_f; for( const l of this.links ) { - this.updateLink(l, visibility); + this.updateLink(l); } for( const f of this.faces ) { diff --git a/gui.js b/gui.js index e2419c5..ab71a9a 100644 --- a/gui.js +++ b/gui.js @@ -1,5 +1,20 @@ import { GUI } from 'lil-gui'; +const SHAPES = [ + 'dodecahedron', '5-cell', '16-cell', 'tesseract', + '24-cell', '600-cell', '120-cell', + '120-cell-layers', '120-cell-all-inscribed' + ]; + +const SHAPE_OPTIONS = { + 'dodecahedron': [ 'inscribed', 'all_inscribed'], + 'tesseract': [ 'inscribed', 'all_inscribed'], + '16-cell': [ 'inscribed', 'all_inscribed'], + '24-cell': [ 'inscribed', 'all_inscribed'], + '600-cell': [ 'inscribed', 'all_inscribed'], + '120-cell': [ 'inscribed', 'all_inscribed'], + '120-cell-layers': [ '0', '1', '2', '3' ,'4', '5', '6' ] +}; const DEFAULTS = { @@ -45,14 +60,16 @@ class FourDGUI { dpsi: this.link['dpsi'], "copy link": function () { guiObj.copyUrl() } }; - - this.gui.add(this.params, 'shape', - [ 'dodecahedron', '5-cell', '16-cell', 'tesseract', - '24-cell', '600-cell', '120-cell', - '120-cell-a', '120-cell-b', '120-cell-c', '120-cell-d', '120-cell-e', '120-cell-f' ] - ).onChange(changeShape) - this.gui.add(this.params, 'inscribed').onChange(changeShape); - this.gui.add(this.params, 'inscribe_all').onChange(changeShape); + let options_ctrl; + this.gui.add(this.params, 'shape', SHAPES).onChange((v) => { + if( SHAPE_OPTIONS[v] ) { + options_ctrl = options_ctrl.options(SHAPE_OPTIONS[v]); + } else { + options_ctrl = options_ctrl.options([]) + } + changeShape(v) + }); + options_ctrl = this.gui.add(this.params, 'options', []); this.gui.add(this.params, 'hyperplane', 1.5, 2.25); this.gui.add(this.params, 'thickness', 0.1, 2); this.gui.add(this.params, 'linkopacity', 0, 1).onChange( @@ -62,7 +79,6 @@ class FourDGUI { (v) => setLinkOpacity(v, false) ); this.gui.add(this.params, 'nodesize', 0.1, 4); - this.gui.add(this.params, 'visibility', [ 0, 1, 2, 3, 4, 5 ]).onChange((v) => setVisibility(v)); this.gui.addColor(this.params, 'color').onChange(setColor); this.gui.addColor(this.params, 'background').onChange(setBackground); this.gui.add(this.params, 'rotation', [ 'rigid', 'tumbling', 'inside-out', 'axisymmetrical' ]); diff --git a/main.js b/main.js index 5ea95ff..b75079d 100644 --- a/main.js +++ b/main.js @@ -61,10 +61,11 @@ for( const face_m of face_ms ) { face_m.opacity = FACE_OPACITY; } -// the best way to do this - -// each STRUCTURE should present a menu of OPTIONS which -// are say a set of inscribed shapes, or a subset etc -// ie 120-cell - inscribed, layers, hopf fibrations etc +// generalisation of the inscription stuff + +// structure - with labels on nodes and links +// options - a set of menu items, each one has a node and link filter + const STRUCTURES = { '5-cell': POLYTOPES.cell5(), @@ -73,12 +74,8 @@ const STRUCTURES = { '24-cell': POLYTOPES.cell24(), 'dodecahedron': POLYTOPES.dodecahedron(), '120-cell': POLYTOPES.cell120(), - '120-cell-a': POLYTOPES.cell120_layered(1), - '120-cell-b': POLYTOPES.cell120_layered(2), - '120-cell-c': POLYTOPES.cell120_layered(3), - '120-cell-d': POLYTOPES.cell120_layered(4), - '120-cell-e': POLYTOPES.cell120_layered(5), - '120-cell-f': POLYTOPES.cell120_layered(6), + '120-cell-layers': POLYTOPES.cell120_layered(), + '120-cell-all-inscribed': POLYTOPES.cell120_all_inscribed(), '600-cell': POLYTOPES.cell600(), }; @@ -150,6 +147,9 @@ function setLinkOpacity(o, primary) { let gui; // let visible_labels = 6; +let node_prune = () => true; +let link_prune = () => true; + function changeShape() { createShape(gui.params.shape, gui.params.inscribed, gui.params.inscribe_all); } @@ -159,6 +159,8 @@ function setVisibility(v) { visible_labels = v; } + + gui = new FourDGUI(changeShape, setColors, setBackground, setLinkOpacity, setVisibility); // these are here to pick up colour settings from the URL params @@ -221,7 +223,7 @@ function animate() { shape.hyperplane = gui.params.hyperplane; shape.link_scale = gui.params.thickness; shape.node_scale = gui.params.nodesize; - shape.render3(rotations, (l) => l <= visible_labels); + shape.render3(rotations, node_prune, link_prune); renderer.render( scene, camera ); } diff --git a/polytopes.js b/polytopes.js index f57a553..5096fb0 100644 --- a/polytopes.js +++ b/polytopes.js @@ -422,15 +422,9 @@ export const cell120_layered = (max) => { layered_120cell(nodes); - const layer_nodes = nodes.filter((n) => n.label < max); - const layer_links = links.filter((l) => { - const labels = link_labels(nodes, l); - return labels[0] < max && labels[1] < max - }); - return { - nodes: layer_nodes, - links: layer_links, + nodes: nodes, + links: links, geometry: { node_size: 0.02, link_size: 0.02