Coloured links for 24-cell

feature-big-polytopes
Mike Lynch 2023-07-25 09:34:53 +10:00
parent 63c3eb1dfe
commit 4cc2b44e00
3 changed files with 55 additions and 31 deletions

View File

@ -19,16 +19,26 @@ function fourDtoV3(x, y, z, w, rotations) {
class FourDShape extends THREE.Group { class FourDShape extends THREE.Group {
constructor(node_ms, link_m, structure) { constructor(node_ms, link_ms, structure) {
super(); super();
this.node_ms = node_ms; this.node_ms = node_ms;
this.link_m = link_m; this.link_ms = link_ms;
this.nodes4 = structure.nodes; this.nodes4 = structure.nodes;
this.nodes3 = {}; this.nodes3 = {};
this.links = structure.links; this.links = structure.links;
this.initShapes(); 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) { makeNode(material, v3) {
const geometry = new THREE.SphereGeometry(NODE_SIZE); const geometry = new THREE.SphereGeometry(NODE_SIZE);
const sphere = new THREE.Mesh(geometry, material); const sphere = new THREE.Mesh(geometry, material);
@ -37,14 +47,14 @@ class FourDShape extends THREE.Group {
return sphere; return sphere;
} }
makeLink(link) { makeLink(material, link) {
const n1 = this.nodes3[link.source].v3; const n1 = this.nodes3[link.source].v3;
const n2 = this.nodes3[link.target].v3; const n2 = this.nodes3[link.target].v3;
const length = n1.distanceTo(n2); const length = n1.distanceTo(n2);
const centre = new THREE.Vector3(); const centre = new THREE.Vector3();
centre.lerpVectors(n1, n2, 0.5); centre.lerpVectors(n1, n2, 0.5);
const geometry = new THREE.CylinderGeometry(LINK_SIZE, LINK_SIZE, 1); 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(); const edge = new THREE.Group();
edge.add(cyl); edge.add(cyl);
edge.position.copy(centre); edge.position.copy(centre);
@ -70,14 +80,15 @@ class FourDShape extends THREE.Group {
initShapes() { initShapes() {
for( const n of this.nodes4 ) { for( const n of this.nodes4 ) {
const v3 = fourDtoV3(n.x, n.y, n.z, n.w, []); 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] = { this.nodes3[n.id] = {
v3: v3, v3: v3,
object: this.makeNode(material, v3) object: this.makeNode(material, v3)
}; };
} }
for( const l of this.links ) { 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);
} }
} }

35
main.js
View File

@ -108,17 +108,13 @@ document.body.appendChild( renderer.domElement );
const struct = POLYTOPES.cell24(); const struct = POLYTOPES.cell24();
// TODO = automate going from struct labels to colours, this now only const node_ms = [
// works with the 24-cell new THREE.MeshStandardMaterial( { color: 0x990000 } ),
new THREE.MeshStandardMaterial( { color: 0x009900 } ),
new THREE.MeshStandardMaterial( { color: 0x000099 } ),
];
const node_ms = {}; for( const node_m of 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];
node_m.roughness = 0.2; node_m.roughness = 0.2;
if( NODE_OPACITY < 1.0 ) { 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( for( const link_m of link_ms ) {
{ color: 0xb0b0b0 } );
link_m.metalness = 0.4; link_m.metalness = 0.4;
link_m.roughness = 0.0; link_m.roughness = 0.0;
if( LINK_OPACITY < 1.0 ) { if( NODE_OPACITY < 1.0 ) {
link_m.transparent = true; node_m.transparent = true;
link_m.opacity = LINK_OPACITY; 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); scene.add(shape);

View File

@ -1,5 +1,7 @@
const r5 = Math.sqrt(5); const r5 = Math.sqrt(5);
// if nodes or links have no label, use the first material in the
// list
export const CELL5 = { export const CELL5 = {
nodes: [ nodes: [
@ -127,11 +129,19 @@ export const TESSERACT = {
// this was done manually and I'm not sure if it's right // this was done manually and I'm not sure if it's right
const CELL24_INDEXING = { const CELL24_INDEXING = {
x: { y: 'RED', z: 'BLUE', w: 'GREEN' }, x: { y: 0, z: 2, w: 1 },
y: { z: 'GREEN', w: 'BLUE' }, y: { z: 1, w: 2 },
z: { w: 'RED' } 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() { function make_24cell_vertices() {
const axes = [ 'x', 'y', 'z', 'w' ]; const axes = [ 'x', 'y', 'z', 'w' ];
const nodes = []; const nodes = [];
@ -179,7 +189,8 @@ function make_24cell_edges(nodes) {
const fp = ids.join(','); const fp = ids.join(',');
if( !seen[fp] ) { if( !seen[fp] ) {
seen[fp] = true; 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 nodes = make_24cell_vertices();
const links = make_24cell_edges(nodes); const links = make_24cell_edges(nodes);
return { nodes: nodes, links: links, labels: [ "RED", "GREEN", "BLUE" ] }; return {
nodes: nodes,
links: links
};
} }