Published
Edited
Jan 20, 2021
3 stars
Insert cell
Insert cell
Insert cell
nSteps = 10
Insert cell
{
const renderer = new THREE.WebGLRenderer({ antialias: true });
invalidation.then(() => renderer.dispose());
renderer.setSize(width, height);
renderer.setPixelRatio(devicePixelRatio);
while (true) {
renderer.render(scene, camera);

const x = createNumbers();

const t = Date.now() / 1000;
const a = 0.5;
const b = 0.5;
const f = (f, p) => Math.max(0, a + Math.sin(t * f + p) * b);
for (let i = 0; i < nSteps; i++) {
const j = i + nSteps;
const k = j + nSteps;
x[i] = f(frequency[i], phase[i]);
y[i] = f(frequency[j], phase[j]);
z[i] = f(frequency[k], phase[k]);
}

const xn = d3.cumsum(x);
const xnm = d3.max(xn);
const yn = d3.cumsum(y);
const ynm = d3.max(yn);
const zn = d3.cumsum(z);
const znm = d3.max(zn);

cubes.forEach((cube, index) => {
const [i, j, k] = triples[index];

cube.position.x = xn[i] / 2 / xnm;
cube.position.y = yn[j] / 2 / ynm;
cube.position.z = zn[k] / 2 / znm;

cube.scale.x = xn[i] / xnm;
cube.scale.y = yn[j] / ynm;
cube.scale.z = zn[k] / znm;
});

yield renderer.domElement;
}
}
Insert cell
scene = {
const scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
cubes.forEach(cube => scene.add(cube));
return scene;
}
Insert cell
cubes = {
const material = new THREE.MeshNormalMaterial();
const geometry = new THREE.BoxGeometry(1, 1, 1);
return triples.map(([i, j, k]) => {
const cube = new THREE.Mesh(geometry, material);
return cube;
});
}
Insert cell
camera = {
const fov = 45;
const aspect = width / height;
const near = 0.1;
const far = 4;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
const d = 2;
camera.position.x = d;
camera.position.y = d;
camera.position.z = d;
camera.lookAt(0, 0, 0);
return camera;
}
Insert cell
triples = {
const triples = [];
for (let i = 0; i < nSteps; i++) {
for (let j = 0; j < nSteps; j++) {
for (let k = 0; k < nSteps; k++) {
if (i + j + k === nSteps - 1) {
triples.push([i, j, k]);
}
}
}
}
return triples;
}
Insert cell
nCubes = triples.length
Insert cell
createNumbers = () =>
d3.cumsum(Array.from({ length: nSteps }, () => Math.random() / nSteps))
Insert cell
y = createNumbers()
Insert cell
z = createNumbers()
Insert cell
frequency = Array.from({ length: nSteps * 3 }, () => 1 + Math.random())
Insert cell
phase = Array.from({ length: nSteps * 3 }, () => Math.random() * Math.PI)
Insert cell
Insert cell
height = 600
Insert cell
Insert cell
THREE = require("three@0.99.0/build/three.min.js")
Insert cell
d3 = require("d3");
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