Added basic gui controls

feature-big-polytopes
Mike Lynch 2023-07-25 15:43:26 +10:00
parent 3026183d54
commit b7355aa48c
4 changed files with 77 additions and 15 deletions

View File

@ -7,15 +7,6 @@ const NODE_SIZE = 0.08;
const LINK_SIZE = 0.02; const LINK_SIZE = 0.02;
function fourDtoV3(x, y, z, w, rotations) {
const v4 = new THREE.Vector4(x, y, z, w);
for ( const m4 of rotations ) {
v4.applyMatrix4(m4);
}
const k = HYPERPLANE / (HYPERPLANE + v4.w);
return new THREE.Vector3(v4.x * k, v4.y * k, v4.z * k);
}
class FourDShape extends THREE.Group { class FourDShape extends THREE.Group {
@ -26,9 +17,12 @@ class FourDShape extends THREE.Group {
this.nodes4 = structure.nodes; this.nodes4 = structure.nodes;
this.nodes3 = {}; this.nodes3 = {};
this.links = structure.links; this.links = structure.links;
this.hyperplane = HYPERPLANE;
this.initShapes(); this.initShapes();
} }
// if a node/link has no label, use the 0th material // if a node/link has no label, use the 0th material
getMaterial(entity, materials) { getMaterial(entity, materials) {
@ -77,9 +71,19 @@ class FourDShape extends THREE.Group {
link.object.children[0].rotation.x = Math.PI / 2.0; link.object.children[0].rotation.x = Math.PI / 2.0;
} }
fourDtoV3(x, y, z, w, rotations) {
const v4 = new THREE.Vector4(x, y, z, w);
for ( const m4 of rotations ) {
v4.applyMatrix4(m4);
}
const k = this.hyperplane / (this.hyperplane + v4.w);
return new THREE.Vector3(v4.x * k, v4.y * k, v4.z * k);
}
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 = this.fourDtoV3(n.x, n.y, n.z, n.w, []);
const material = this.getMaterial(n, this.node_ms); const material = this.getMaterial(n, this.node_ms);
this.nodes3[n.id] = { this.nodes3[n.id] = {
v3: v3, v3: v3,
@ -92,9 +96,10 @@ class FourDShape extends THREE.Group {
} }
} }
render3(rotations) { render3(rotations) {
for( const n of this.nodes4 ) { for( const n of this.nodes4 ) {
const v3 = fourDtoV3(n.x, n.y, n.z, n.w, rotations); const v3 = this.fourDtoV3(n.x, n.y, n.z, n.w, rotations);
this.nodes3[n.id].v3 = v3; this.nodes3[n.id].v3 = v3;
this.nodes3[n.id].object.position.copy(v3); this.nodes3[n.id].object.position.copy(v3);
// could do scaling here // could do scaling here

58
main.js
View File

@ -4,6 +4,7 @@ import * as POLYTOPES from './polytopes.js';
import { FourDShape } from './fourDShape.js'; import { FourDShape } from './fourDShape.js';
import { GUI } from 'lil-gui';
@ -149,12 +150,29 @@ for( const link_m of link_ms ) {
} }
} }
const struct = POLYTOPES.cell24(); const STRUCTURES = {
'5-cell': POLYTOPES.cell5(),
'16-cell': POLYTOPES.cell16(),
'tesseract': POLYTOPES.tesseract(),
'24-cell': POLYTOPES.cell24(),
};
let shape = false;
function createShape(name) {
if( shape ) {
scene.remove(shape);
}
shape = new FourDShape(node_ms, link_ms, STRUCTURES[name]);
scene.add(shape);
}
const shape = new FourDShape(node_ms, link_ms, struct);
scene.add(shape);
createShape('24-cell');
camera.position.z = 4; camera.position.z = 4;
@ -185,6 +203,34 @@ renderer.domElement.addEventListener("mousemove", (event) => {
} }
}) })
// set up GUI
const gui = new GUI();
const gui_params = {
shape: '24-cell',
hyperplane: 2,
xRotate: 'YW',
yRotate: 'XZ',
};
gui.add(gui_params, 'shape',
[ '5-cell', '16-cell', 'tesseract', '24-cell' ]
).onChange(createShape)
gui.add(gui_params, 'hyperplane', 1, 4);
gui.add(gui_params, 'xRotate', [ 'YW', 'YZ', 'ZW' ]);
gui.add(gui_params, 'yRotate', [ 'XZ', 'XY', 'XW' ]);
const ROTFN = {
XY: rotXY,
XZ: rotXZ,
XW: rotXW,
YZ: rotYZ,
YW: rotYW,
ZW: rotZW,
};
const rotation = new THREE.Matrix4(); const rotation = new THREE.Matrix4();
@ -192,7 +238,11 @@ const rotation = new THREE.Matrix4();
function animate() { function animate() {
requestAnimationFrame( animate ); requestAnimationFrame( animate );
const rotations = [rotYZ(theta), rotXZ(psi)]; const rotations = [
ROTFN[gui_params.xRotate](theta),
ROTFN[gui_params.yRotate](psi)
];
shape.hyperplane = gui_params.hyperplane;
shape.render3(rotations); shape.render3(rotations);
renderer.render( scene, camera ); renderer.render( scene, camera );

6
package-lock.json generated
View File

@ -5,6 +5,7 @@
"packages": { "packages": {
"": { "": {
"dependencies": { "dependencies": {
"lil-gui": "^0.18.2",
"three": "^0.154.0" "three": "^0.154.0"
}, },
"devDependencies": { "devDependencies": {
@ -414,6 +415,11 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0" "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
} }
}, },
"node_modules/lil-gui": {
"version": "0.18.2",
"resolved": "https://registry.npmjs.org/lil-gui/-/lil-gui-0.18.2.tgz",
"integrity": "sha512-DgdrLy3/KGC0PiQLKgOcJMPItP4xY4iWgJ9+91Zaxfr8GCTmMps05QS9w9jW7yspILlbscbquwjOwxmWnSx5Uw=="
},
"node_modules/nanoid": { "node_modules/nanoid": {
"version": "3.3.6", "version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",

View File

@ -1,5 +1,6 @@
{ {
"dependencies": { "dependencies": {
"lil-gui": "^0.18.2",
"three": "^0.154.0" "three": "^0.154.0"
}, },
"devDependencies": { "devDependencies": {