Added TaperedLink class, still very broken but I think this approach

to properly-scaled links is viable
This commit is contained in:
Mike Lynch 2024-05-28 17:40:30 +10:00
parent 0ada3fce6f
commit c8b3f1902a
4 changed files with 50 additions and 18 deletions

View File

@ -1,9 +1,12 @@
import * as THREE from 'three';
import { TaperedLink } from './taperedLink.js';
const HYPERPLANE = 2.0;
const W_FORESHORTENING = 0.04;
class FourDShape extends THREE.Group {
constructor(node_ms, link_ms, face_ms, structure) {
@ -42,7 +45,7 @@ class FourDShape extends THREE.Group {
return sphere;
}
makeLink(material, link) {
makeLink(basematerial, link) {
const n1 = this.nodes3[link.source];
const n2 = this.nodes3[link.target];
const s1 = n1.scale;
@ -50,17 +53,11 @@ class FourDShape extends THREE.Group {
const length = n1.v3.distanceTo(n2.v3);
const centre = new THREE.Vector3();
centre.lerpVectors(n1.v3, n2.v3, 0.5);
const geometry = new THREE.CylinderGeometry(
this.link_scale * s2, this.link_scale * s1, 1,
16, 1, true
);
const cyl = new THREE.Mesh(geometry, material);
const edge = new THREE.Group();
edge.add(cyl);
const edge = new TaperedLink(basematerial);
edge.update(s1, s2, length);
edge.position.copy(centre);
edge.scale.copy(new THREE.Vector3(1, 1, length));
edge.lookAt(n2.v3);
cyl.rotation.x = Math.PI / 2.0;
this.add(edge);
return edge;
}
@ -73,14 +70,9 @@ class FourDShape extends THREE.Group {
const length = n1.v3.distanceTo(n2.v3);
const centre = new THREE.Vector3();
centre.lerpVectors(n1.v3, n2.v3, 0.5);
// take the average of the ends as the thickness - as a workaround,
// because I haven't worked out how to reshape tapered links without
// having to reassign a new geometry to every link
const link_mean = this.link_scale * (s1 + s2) * 0.5;
link.object.scale.copy(new THREE.Vector3(link_mean, link_mean, length));
link.object.position.copy(centre);
link.object.update(s1, s2, length);
link.object.position.copy(n1.v3);
link.object.lookAt(n2.v3);
link.object.children[0].rotation.x = Math.PI / 2.0;
link.object.visible = (!links_show || link.label in links_show);
}

2
gui.js
View File

@ -7,7 +7,7 @@ const DEFAULTS = {
linksize: 0.2,
linkopacity: 0.75,
link2opacity: 0.75,
shape: '120-cell',
shape: '16-cell',
option: 'none',
visibility: 5,
inscribed: false,

View File

@ -31,6 +31,10 @@ camera.lookAt(0, 0, 0);
const renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.localClippingEnabled = true;
document.body.appendChild( renderer.domElement );
// set up colours and materials for gui callbacks

36
taperedLink.js Normal file
View File

@ -0,0 +1,36 @@
import * as THREE from 'three';
class TaperedLink extends THREE.Group {
constructor(baseMaterial) {
super();
const geometry = new THREE.ConeGeometry( 0.75, 1, 32, true );
const cplane = new THREE.Plane(new THREE.Vector3(0, -1, 0), 0.5);
const material = baseMaterial.clone();
material.clippingPlanes = [ cplane ];
this.object = new THREE.Mesh( geometry, material );
this.add( this.object );
}
update(r1, r2, l) {
const kraw = ( r1 - r2 );
const k = ( kraw == 0 ) ? 0.001 : kraw;
if( k > 0 ) {
const h = l * r1 / k;
this.object.scale.copy(new THREE.Vector3(r1, h, r1));
this.object.material.clippingPlanes[0].normal.y = -1;
this.object.material.clippingPlanes[0].constant = l / 2;
this.object.position.copy(new THREE.Vector3(0, h/2 - l/2, 0));
} else {
const h = l * r2 / k;
this.object.scale.copy(new THREE.Vector3(r2, h, r2));
this.object.material.clippingPlanes[0].normal.y = 1;
this.object.material.clippingPlanes[0].constant = l / 2;
this.object.position.copy(new THREE.Vector3(0, h / 2 + l / 2, 0));
}
}
}
export { TaperedLink };