Published
Edited
Dec 4, 2018
3 stars
Insert cell
Insert cell
Insert cell
Insert cell
function setup() {
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(45, width / height, 1, 1000)
const renderer = new THREE.WebGLRenderer()
const controls = new THREE.OrbitControls(camera, renderer.domElement);
// set renderer size
renderer.setSize(width, height)
// set camera position
camera.position.set( 0, 0, 100 )
camera.lookAt( 0, 0, 0 )
controls.addEventListener("change", () => renderer.render(scene, camera));
return {scene, camera, renderer}
}
Insert cell
Insert cell
{
// set up scene, camera, and renderer
const {scene, camera, renderer} = setup()
// create just one triangle
const vertices = [
0, 1, 0, // top
0.5, 0, 1, // right
-0.5, 0, 1 // left
]
const faces = [
// 0, 1, 2 // only one face
2, 1, 0
]
const geometry = new THREE.PolyhedronGeometry(vertices, faces, 20, 0)
const material = new THREE.MeshNormalMaterial()
const triangle = new THREE.Mesh(geometry, material)
scene.add(triangle)
// tell renderer to render scene & camera
renderer.render(scene, camera);
// return the renderer's canvas element
// but normally would want to append it to the DOM
return renderer.domElement
}
Insert cell
Insert cell
{
// set up scene, camera, and renderer
const {scene, camera, renderer} = setup()
// create just one triangle
const front = Math.tan(Math.PI / 6)
const back = Math.cos(Math.PI / 6)
const vertices = [
0, 1, 0, // 0: top
1, 0, front, // 1: right
-1, 0, front, // 2: left
0, 0, -back, // 3: back middle
0, -1, 0, // 4: bottom
]
const faces = [
2, 1, 0, // left, right, top
1, 3, 0, // right, back, top
3, 2, 0, // back, left, top
2, 4, 1, // left, bottom, right
1, 4, 3, // right, bottom, back
3, 4, 2, // back, bottom, left
]
const geometry = new THREE.PolyhedronGeometry(vertices, faces, 30, 0)
const material = new THREE.MeshNormalMaterial()
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)
// scale the mesh
mesh.scale.set(0.5, 1, 0.5)
// rotate, render, and return dom element
while (true) {
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
yield renderer.domElement;
}
}
Insert cell
Insert cell
{
// set up scene, camera, and renderer
const {scene, camera, renderer} = setup()
// Geometry parameters
const sides = 4;
const height = 20;
const capHeight = 5;
const radius = 10;

// The middle part of the crystal, with open-ended top and bottom faces
const middle = new THREE.CylinderGeometry(radius, radius, height, sides, 1, true);

// Create an open-ended cone
const coneTop = new THREE.ConeGeometry(radius, capHeight, sides, 1, true);
// Clone it so we have two different geometries (one for each end)
const coneBottom = coneTop.clone();

// Move the top cap up to the correct place
coneTop.translate(0, height / 2 + capHeight / 2, 0);
// First flip the bottom cap, then move it down
coneBottom.rotateZ(Math.PI);
coneBottom.translate(0, -height / 2 - capHeight / 2, 0);
// Now construct our final geometry
const geometry = new THREE.Geometry();
geometry.merge(middle);
geometry.merge(coneTop);
geometry.merge(coneBottom);
// Notice I am using flat shading in the material, to give it a faceted look.
// Most ThreeJS geometries will appear smooth by default.
const material = new THREE.MeshNormalMaterial({ flatShading: true });
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)
// scale the mesh
mesh.scale.set(0.5, 1, 0.5)
while (true) {
mesh.rotation.y += 0.01;
renderer.render(scene, camera);
yield renderer.domElement;
}
}
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more