From 4cc2b44e00a09f772885bf5468597200f522210b Mon Sep 17 00:00:00 2001 From: Mike Lynch Date: Tue, 25 Jul 2023 09:34:53 +1000 Subject: [PATCH] Coloured links for 24-cell --- fourDShape.js | 23 +++++++++++++++++------ main.js | 39 +++++++++++++++++++-------------------- polytopes.js | 24 +++++++++++++++++++----- 3 files changed, 55 insertions(+), 31 deletions(-) diff --git a/fourDShape.js b/fourDShape.js index 2893b6b..c4b61dc 100644 --- a/fourDShape.js +++ b/fourDShape.js @@ -19,16 +19,26 @@ function fourDtoV3(x, y, z, w, rotations) { class FourDShape extends THREE.Group { - constructor(node_ms, link_m, structure) { + constructor(node_ms, link_ms, structure) { super(); this.node_ms = node_ms; - this.link_m = link_m; + this.link_ms = link_ms; this.nodes4 = structure.nodes; this.nodes3 = {}; this.links = structure.links; this.initShapes(); } + // if a node/link has no label, use the 0th material + + getMaterial(entity, materials) { + if( "label" in entity ) { + return materials[entity.label]; + } else { + return materials[0]; + } + } + makeNode(material, v3) { const geometry = new THREE.SphereGeometry(NODE_SIZE); const sphere = new THREE.Mesh(geometry, material); @@ -37,14 +47,14 @@ class FourDShape extends THREE.Group { return sphere; } - makeLink(link) { + makeLink(material, link) { const n1 = this.nodes3[link.source].v3; const n2 = this.nodes3[link.target].v3; const length = n1.distanceTo(n2); const centre = new THREE.Vector3(); centre.lerpVectors(n1, n2, 0.5); const geometry = new THREE.CylinderGeometry(LINK_SIZE, LINK_SIZE, 1); - const cyl = new THREE.Mesh(geometry, this.link_m); + const cyl = new THREE.Mesh(geometry, material); const edge = new THREE.Group(); edge.add(cyl); edge.position.copy(centre); @@ -70,14 +80,15 @@ class FourDShape extends THREE.Group { initShapes() { for( const n of this.nodes4 ) { const v3 = fourDtoV3(n.x, n.y, n.z, n.w, []); - const material = this.node_ms[n.label]; + const material = this.getMaterial(n, this.node_ms); this.nodes3[n.id] = { v3: v3, object: this.makeNode(material, v3) }; } for( const l of this.links ) { - l.object = this.makeLink(l); + const material = this.getMaterial(l, this.link_ms); + l.object = this.makeLink(material, l); } } diff --git a/main.js b/main.js index 92a5fe9..94eb339 100644 --- a/main.js +++ b/main.js @@ -108,17 +108,13 @@ document.body.appendChild( renderer.domElement ); const struct = POLYTOPES.cell24(); -// TODO = automate going from struct labels to colours, this now only -// works with the 24-cell +const node_ms = [ + new THREE.MeshStandardMaterial( { color: 0x990000 } ), + new THREE.MeshStandardMaterial( { color: 0x009900 } ), + new THREE.MeshStandardMaterial( { color: 0x000099 } ), +]; -const node_ms = {}; - -node_ms["RED"] = new THREE.MeshStandardMaterial( { color: 0x990044 } ); -node_ms["GREEN"] = new THREE.MeshStandardMaterial( { color: 0xffffee } ); -node_ms["BLUE"] = new THREE.MeshStandardMaterial( { color: 0x101010 } ); - -for( const label in node_ms ) { - const node_m = node_ms[label]; +for( const node_m of node_ms ) { node_m.roughness = 0.2; if( NODE_OPACITY < 1.0 ) { @@ -127,21 +123,24 @@ for( const label in node_ms ) { } } +const link_ms = [ + new THREE.MeshStandardMaterial( { color: 0x999900 } ), + new THREE.MeshStandardMaterial( { color: 0x009999 } ), + new THREE.MeshStandardMaterial( { color: 0x990099 } ), + ]; -const link_m = new THREE.MeshStandardMaterial( - { color: 0xb0b0b0 } ); +for( const link_m of link_ms ) { + link_m.metalness = 0.4; + link_m.roughness = 0.0; - -link_m.metalness = 0.4; -link_m.roughness = 0.0; - -if( LINK_OPACITY < 1.0 ) { - link_m.transparent = true; - link_m.opacity = LINK_OPACITY; + if( NODE_OPACITY < 1.0 ) { + node_m.transparent = true; + node_m.opacity = NODE_OPACITY; + } } -const shape = new FourDShape(node_ms, link_m, struct); +const shape = new FourDShape(node_ms, link_ms, struct); scene.add(shape); diff --git a/polytopes.js b/polytopes.js index 83149df..1bbcb01 100644 --- a/polytopes.js +++ b/polytopes.js @@ -1,5 +1,7 @@ const r5 = Math.sqrt(5); +// if nodes or links have no label, use the first material in the +// list export const CELL5 = { nodes: [ @@ -127,11 +129,19 @@ export const TESSERACT = { // this was done manually and I'm not sure if it's right const CELL24_INDEXING = { - x: { y: 'RED', z: 'BLUE', w: 'GREEN' }, - y: { z: 'GREEN', w: 'BLUE' }, - z: { w: 'RED' } + x: { y: 0, z: 2, w: 1 }, + y: { z: 1, w: 2 }, + z: { w: 0 }, }; +// note that this depends on the colour mapping in main.js, yuck + +const CELL24_LINK_INDEXING = { + 0: { 1: 0, 2: 2 }, + 1: { 0: 0, 2: 1 }, + 2: { 0: 2, 1: 1 }, +} + function make_24cell_vertices() { const axes = [ 'x', 'y', 'z', 'w' ]; const nodes = []; @@ -179,7 +189,8 @@ function make_24cell_edges(nodes) { const fp = ids.join(','); if( !seen[fp] ) { seen[fp] = true; - links.push({ id: id, source: n1.id, target: n2.id }); + const label = CELL24_LINK_INDEXING[n1.label][n2.label]; + links.push({ id: id, label: label, source: n1.id, target: n2.id }); } } } @@ -190,6 +201,9 @@ export const cell24 = () => { const nodes = make_24cell_vertices(); const links = make_24cell_edges(nodes); - return { nodes: nodes, links: links, labels: [ "RED", "GREEN", "BLUE" ] }; + return { + nodes: nodes, + links: links + }; }