Public
Edited
May 11, 2024
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Continuously updates
{
let i = 0,
n = data.length;

while (true) {
i += 1;
i %= n;
let { dtheta, theta, omega } = data[i];

if (i === 0) {
cube.rotation.z -= cube.rotation.z;
cube.rotation.x -= cube.rotation.x;
cube.rotation.x += options.theta0;
} else {
// cube.rotation.z += 0.01;
cube.rotation.z += omega * dt;
cube.rotation.x += dtheta;
}

renderer.render(scene, camera);
yield i;
}
}
Insert cell
data = {
let { mass1, radius1, mass2, radius2, omega0, theta0 } = options,
omega = omega0,
theta = theta0,
dtheta = 0,
data = [Object.assign({}, { omega, theta, dtheta })];

let obj;
for (let i = 0; i < num; ++i) {
obj = update(theta, dtheta);
data.push(Object.assign({}, obj));
theta = obj.theta;
dtheta = obj.dtheta;
}

data.map((d) => Object.assign(d, { mass1, radius1, mass2, radius2 }));

return data;
}
Insert cell
data
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
Insert cell
update = (theta, dtheta) => {
let { mass1, radius1, mass2, radius2 } = options,
omega = computeOmega(theta),
r = radius2 * Math.sin(theta),
kineticEnergy =
0.5 * mass2 * Math.pow(r * omega, 2) +
0.5 * mass1 * Math.pow(radius1 * omega, 2),
a = r * r * omega,
dr = Math.cos(theta) * a * dt;
// dr = Math.sign(Math.cos(theta)) * a * dt;

dtheta += dr / radius2;
theta += dtheta;

return { omega, theta, dtheta, kineticEnergy };
}
Insert cell
computeOmega(options.theta0)
Insert cell
computeOmega = (theta) => {
let { mass1, radius1, mass2, radius2 } = options;

return (
fixedRotationMoment / (mass1 * radius1 + mass2 * radius2 * Math.sin(theta))
);
}
Insert cell
fixedRotationMoment = {
let { mass1, radius1, mass2, radius2, omega0, theta0 } = options;

return (mass1 * radius1 + mass2 * radius2 * Math.sin(theta0)) * omega0;
}
Insert cell
Insert cell
height = 600
Insert cell
cube = {
const material = new THREE.MeshNormalMaterial();
const geometry = new THREE.BoxGeometry(5, 2, 1);
const cube = new THREE.Mesh(geometry, material);

cube.rotation.x += options.theta0;

return cube;
}
Insert cell
scene = {
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x001b42);
scene.add(cube);
return scene;
}
Insert cell
camera = {
const fov = 45;
const aspect = width / height;
const near = 1;
const far = 1000;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(5, 6, -5);
camera.lookAt(new THREE.Vector3(0, 0, 0));
return camera;
}
Insert cell
renderer = {
const renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(width, height);
renderer.setPixelRatio(devicePixelRatio);
const controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", () => renderer.render(scene, camera));
invalidation.then(() => (controls.dispose(), renderer.dispose()));
return renderer;
}
Insert cell
THREE = {
const THREE = window.THREE = await require("three@0.130.0/build/three.min.js");
await require("three@0.130.0/examples/js/controls/OrbitControls.js").catch(() => {});
return THREE;
}
Insert cell
Insert cell
Insert cell
Insert cell
elasticData = {
let data = [],
x = 1,
v = 0,
k = 0.01;

for (let i = 0; i < num; ++i) {
v -= x * k * dt;
x += v;
data.push({ x, v, ke: 0.5 * v * v });
}

return data;
}
Insert cell
elasticData
Type Table, then Shift-Enter. Ctrl-space for more options.

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