diff --git a/gui.js b/gui.js index cdba062..921a98f 100644 --- a/gui.js +++ b/gui.js @@ -6,7 +6,10 @@ const DEFAULTS = { thickness: 0.25, nodesize: 1.25, linkopacity: 0.5, + link2opacity: 0.5, shape: '120-cell', + inscribed: false, + inscribe_all: false, color: 0x3293a9, background: 0xd4d4d4, hyperplane: 2, @@ -19,14 +22,17 @@ const DEFAULTS = { class FourDGUI { - constructor(createShape, setColor, setBackground, setLinkOpacity) { + constructor(changeShape, setColor, setBackground, setLinkOpacity) { this.gui = new GUI(); this.parseLinkParams(); const guiObj = this; this.params = { shape: this.link['shape'], + inscribed: this.link['inscribed'], + inscribe_all: this.link['inscribe_all'], thickness: this.link['thickness'], linkopacity: this.link['linkopacity'], + link2opacity: this.link['linkopacity'], nodesize: this.link['nodesize'], color: this.link['color'], background: this.link['background'], @@ -39,12 +45,19 @@ class FourDGUI { }; this.gui.add(this.params, 'shape', - [ '5-cell', '16-cell', 'tesseract', '24-cell', '600-cell', '120-cell', '120-cell-inscribed' ] - ).onChange(createShape) - + [ '5-cell', '16-cell', 'tesseract', + '24-cell', '600-cell', '120-cell' ] + ).onChange(changeShape) + this.gui.add(this.params, 'inscribed').onChange(changeShape); + this.gui.add(this.params, 'inscribe_all').onChange(changeShape); 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(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.add(this.params, 'nodesize', 0.1, 4); this.gui.addColor(this.params, 'color').onChange(setColor); this.gui.addColor(this.params, 'background').onChange(setBackground); @@ -79,6 +92,7 @@ class FourDGUI { parseLinkParams() { this.linkUrl = new URL(window.location.toLocaleString()); this.link = {}; + const guiObj = this; this.urlParams = this.linkUrl.searchParams; for( const param of [ "shape", "rotation" ]) { @@ -89,10 +103,13 @@ class FourDGUI { this.link[param] = DEFAULTS[param]; } } - const guiObj = this; + for( const param of [ "inscribed", "inscribe_all"] ) { + this.link[param] = ( this.urlParams.get(param) === 'y' ); + } this.link['hyperplane'] = this.numParam('hyperplane', parseFloat); this.link['thickness'] = this.numParam('thickness', parseFloat); this.link['linkopacity'] = this.numParam('linkopacity', parseFloat); + this.link['link2opacity'] = this.numParam('link2opacity', parseFloat); this.link['nodesize'] = this.numParam('nodesize', parseFloat); this.link['color'] = this.numParam('color', (s) => guiObj.stringToHex(s)); this.link['background'] = this.numParam('background', (s) => guiObj.stringToHex(s)); @@ -104,8 +121,12 @@ class FourDGUI { copyUrl() { const url = new URL(this.linkUrl.origin + this.linkUrl.pathname); url.searchParams.append("shape", this.params.shape); + url.searchParams.append("inscribed", this.params.inscribed ? 'y': 'n'); + url.searchParams.append("inscribe_all", this.params.inscribe_all ? 'y': 'n'); url.searchParams.append("thickness", this.params.thickness.toString()); url.searchParams.append("nodesize", this.params.nodesize.toString()); + url.searchParams.append("linkopacity", this.params.thickness.toString()); + url.searchParams.append("link2opacity", this.params.nodesize.toString()); url.searchParams.append("color", this.hexToString(this.params.color)); url.searchParams.append("background", this.hexToString(this.params.background)); url.searchParams.append("hyperplane", this.params.hyperplane.toString()); diff --git a/main.js b/main.js index f57802c..1cb3ed4 100644 --- a/main.js +++ b/main.js @@ -65,17 +65,39 @@ const STRUCTURES = { 'tesseract': POLYTOPES.tesseract(), '24-cell': POLYTOPES.cell24(), '120-cell': POLYTOPES.cell120(), - '120-cell-inscribed': POLYTOPES.cell120_inscribed(), - '600-cell': POLYTOPES.cell600() + '120-cell-all-inscribed': POLYTOPES.cell120_all_inscribed(), + '600-cell': POLYTOPES.cell600(), + '600-cell-all-inscribed': POLYTOPES.cell600_all_inscribed(), }; +const INSCRIBED = { + '120-cell': POLYTOPES.cell120_inscribed(), + '600-cell': POLYTOPES.cell600_inscribed(), +}; + +const ALL_INSCRIBED = { + '120-cell': POLYTOPES.cell120_all_inscribed(), + '600-cell': POLYTOPES.cell600_all_inscribed(), +} + let shape = false; -function createShape(name) { +function createShape(name, inscribed, all) { if( shape ) { scene.remove(shape); } - shape = new FourDShape(node_ms, link_ms, face_ms, STRUCTURES[name]); + let structure = STRUCTURES[name]; + if( inscribed ) { + if( name in INSCRIBED ) { + if( all ) { + structure = ALL_INSCRIBED[name]; + } else { + structure = INSCRIBED[name]; + } + } + } + + shape = new FourDShape(node_ms, link_ms, face_ms, structure); scene.add(shape); } @@ -97,13 +119,24 @@ function setBackground(c) { scene.background = new THREE.Color(c) } -function setLinkOpacity(o) { - for( const lm of link_ms ) { - lm.opacity = o; - } +function setLinkOpacity(o, primary) { + if( primary ) { + link_ms[0].opacity = o; + } else { + for( const lm of link_ms.slice(1) ) { + lm.opacity = o; + } + } } -const gui = new FourDGUI(createShape, setColors, setBackground, setLinkOpacity); +let gui; // + +function changeShape() { + console.log("change shape!") + createShape(gui.params.shape, gui.params.inscribed, gui.params.inscribe_all); +} + +gui = new FourDGUI(changeShape, setColors, setBackground, setLinkOpacity); // these are here to pick up colour settings from the URL params setColors(gui.params.color); @@ -146,7 +179,7 @@ renderer.domElement.addEventListener("pointerup", (event) => { dragging = false; }) -createShape(gui.params.shape); +createShape(gui.params.shape, gui.params.inscribed, gui.params.inscribe_all); function animate() { requestAnimationFrame( animate ); diff --git a/polytopes.js b/polytopes.js index 8eaa192..07ab69c 100644 --- a/polytopes.js +++ b/polytopes.js @@ -151,6 +151,11 @@ const CELL24_INDEXING = { }; +function node_by_id(nodes, nid) { + const ns = nodes.filter((n) => n.id === nid); + return ns[0]; +} + export const cell24 = () => { const nodes = PERMUTE.coordinates([0, 0, 1, 1], 0); @@ -163,6 +168,15 @@ export const cell24 = () => { index_nodes(nodes); const links = auto_detect_edges(nodes, 8); + links.map((l) => { + const ls = [ l.source, l.target ].map((nid) => node_by_id(nodes, nid).label); + for ( const c of [1, 2, 3] ) { + if( ! ls.includes(c) ) { + l.label = c + } + } + }); + return { nodes: nodes, links: links, @@ -357,7 +371,7 @@ export const cell120 = () => { } -export const cell120_inscribed = () => { +const cell120_some_inscribed = (ps) => { const nodes = make_120cell_vertices(); const links = auto_detect_edges(nodes, 4); @@ -366,7 +380,7 @@ export const cell120_inscribed = () => { const all_links = links; all_links.map((l) => l.label = 0); - for( const p of [ 5 ]) { + for( const p of ps) { const nodes600 = nodes.filter((n) => n.label === p); const links600 = auto_detect_edges(nodes600, 12); links600.map((l) => l.label = p); @@ -383,6 +397,9 @@ export const cell120_inscribed = () => { } } +export const cell120_inscribed = () => cell120_some_inscribed([5]); +export const cell120_all_inscribed = () => cell120_some_inscribed([1,2,3,4,5]); + // Schoute's partition via https://arxiv.org/abs/1010.4353 @@ -518,7 +535,7 @@ function make_600cell_vertices() { ].flat(); for( const n of nodes ) { - n.label = label_vertex(n, coords, partition600) - 1; + n.label = label_vertex(n, coords, partition600); } for( const n of nodes ) { @@ -570,3 +587,42 @@ export const cell600 = () => { } + +const cell600_some_inscribed = (ps) => { + const nodes = make_600cell_vertices(); + const links = auto_detect_edges(nodes, 12); + + const all_links = links; + all_links.map((l) => l.label = 0); + + for( const p of ps) { + const nodes24 = nodes.filter((n) => n.label === p); + const links24 = auto_detect_edges(nodes24, 8); + links24.map((l) => l.label = p); + all_links.push(...links24); + } + + return { + nodes: nodes, + links: all_links, + geometry: { + node_size: 0.02, + link_size: 0.02 + }, + } + + + return { + nodes: nodes, + links: links, + geometry: { + node_size: 0.02, + link_size: 0.02 + } + } +} + + +export const cell600_inscribed = () => cell600_some_inscribed([5]); +export const cell600_all_inscribed = () => cell600_some_inscribed([1,2,3,4,5]); +