enneahedron-3d/script.js

145 lines
3.9 KiB
JavaScript
Raw Permalink Normal View History

2025-04-06 15:54:58 +00:00
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { STLExporter } from 'three/addons/exporters/STLExporter.js';
import { ConvexHull } from 'three/addons/math/ConvexHull.js';
const {BufferGeometry, Float32BufferAttribute, Vector3} = THREE;
import {ConvexGeometry, WireframeGeometry} from './geometries.js';
const scene = new THREE.Scene();
const width = window.innerWidth;
const height = window.innerHeight;
const w = width<height ? 1.3 : (width/height * 1.3);
const h = height/width * w;
const camera = new THREE.OrthographicCamera( -w, w, h, -h, 0, 100);
scene.background = new THREE.Color(0xc49879);
// Create a directional light
const light = new THREE.DirectionalLight(0xffffff, 1.0);
// move the light back and up a bit
light.position.set(0, 3, 3);
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff))
window.v3 = Vector3;
const renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setSize( width, height );
document.getElementById('three-container').appendChild( renderer.domElement );
const scale = 1.5;
renderer.domElement.width = scale*width;
renderer.domElement.height = scale*height;
renderer.setViewport(0,0,scale*width, scale*height);
function make_points(h1,h2) {
h1 = new Vector3(0,0,h1);
h2 = new Vector3(0,0,h2);
const [v1,v3,v10] = [0,1,2].map(i => {
const an = Math.PI*2 * i/3;
return new Vector3(Math.cos(an),Math.sin(an),0);
});
const v0 = v1.clone().add(v3).divideScalar(2).sub(h1);
const v2 = v1.clone().add(v3).divideScalar(2).add(h1);
const v4 = v1.clone().add(v3).add(v10).divideScalar(3).sub(h2);
const v7 = v1.clone().add(v3).add(v10).divideScalar(3).add(h2);
const v5 = v1.clone().add(v10).divideScalar(2).sub(h1);
const v6 = v1.clone().add(v10).divideScalar(2).add(h1);
const v8 = v3.clone().add(v10).divideScalar(2).add(h1);
const v9 = v3.clone().add(v10).divideScalar(2).sub(h1);
const points = [v0,v1,v2,v3,v4,v5,v6,v7,v8,v9,v10];
/*
const x1 = 0.2;
const x2 = 0.4;
const y = 0.5;
const points = [
[1,0,0], // 0
[0,1,0], // 1
[-1,0,0], // 2
[0,-1,0], // 3
[x2,0,h1], // 4
[x1,y,h2], // 5
[-x1,y,h2], // 6
[-x2,0,h1], // 7
[-x1,-y,h2], // 8
[x1,-y,h2], // 9
[0,0,h1+h2] // 10
].map(p => new Vector3(...p));
const [v0,v1,v2,v3,v4,v5,v6,v7,v8,v9,v10] = points;
*/
const edges = [
v0,v1,
v0,v4,
v0,v3,
v1,v2,
v1,v6,
v1,v5,
v2,v3,
v2,v7,
v3,v8,
v3,v9,
v4,v5,
v4,v9,
v5,v10,
v6,v7,
v6,v10,
v7,v8,
v8,v10,
v9,v10
].flatMap(p => [p.x,p.y,p.z]);
return {points,edges};
}
const hull_geometry = new ConvexGeometry( [] );
const hull_material = new THREE.MeshStandardMaterial( { color: 0x93c8ee, transparent: true} );
const hull = new THREE.Mesh( hull_geometry, hull_material );
hull.renderOrder = -1;
scene.add( hull );
const wireframe = new BufferGeometry( [] );
const line = new THREE.LineSegments( wireframe, new THREE.LineBasicMaterial({color: 0x0, transparent: true}) );
line.renderOrder = -1;
scene.add( line );
camera.position.z = 1.8;
const controls = new OrbitControls( camera, renderer.domElement );
hull.rotation.x = line.rotation.x = -Math.PI/2;
//hull.position.y = line.position.y = -0.5;
let i = 0;
function animate() {
i += 1;
const an = i/100;
controls.update();
renderer.render( scene, camera );
const h1 = document.getElementById('h1').valueAsNumber;
const h2 = document.getElementById('h2').valueAsNumber;
const scale = document.getElementById('scale').valueAsNumber;
const {points, edges} = make_points(h1 * scale, h2 * scale);
hull_geometry.setFromPoints(points);
//hull_geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(faces), 3))
wireframe.setAttribute('position', new Float32BufferAttribute(edges,3));
}
renderer.setAnimationLoop( animate );
function vlen([x,y,z]) {
return Math.sqrt(x**2+y**2+z**2);
}