Pendulum with Oscillating Platform
Loosely based on
https://burakkanber.com/blog/physics-in-javascript-rigid-bodies-part-1-pendulum-clock/
HTML
<canvas id="canvas" height="600" width="600"></canvas>
CSS
canvas {
display: block;
margin: 0px auto;
height: 600px;
width: 600px;
border: none;
}
JavaScript
var platform = {
A: 30, // play with me
omega: 1, // play with me
theta: 0,
width: 200,
height: 25,
top: 50
}
var pendulum = {
l: 200, // play with me
theta: Math.PI / 8,
dtheta: 0
};
var g = 9.8; // play with me
//this parameter takes the number of seconds between frames
// and converts it to a Runge Kutta step size
var stepSizeFactor = 2; // step_size/seconds
var height = 600;
var width = 600;
var canvas = false;
var ctx = false;
var lastTime = false;
window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
function runge_kutta_step(theta, dtheta, step) {
var k1 = [0, 0];
var k2 = [0, 0];
var k3 = [0, 0];
var k4 = [0, 0];
// $\ddot{theta} = -\frac{g + \ddot{z}}{l} sin(\theta)
var tmp = ((g - platform.A * Math.pow(platform.omega, 2) * Math.cos(platform.theta)) / pendulum.l) * Math.sin(theta);
k1[0] = step * dtheta;
k1[1] = -step * tmp;
k2[0] = step * (dtheta + k1[1] / 2.0)
k2[1] = -step * (tmp + k1[0] / 2.0)
k3[0] = step * (dtheta + k2[1] / 2.0)
k3[1] = -step * (tmp + k2[0] / 2.0)
k4[0] = step * (dtheta + k3[1])
k4[1] = -step * (tmp + k3[0])
var new_theta = theta + (k1[0] + 2 * k2[0] + 2 * k3[0] + k4[0]) / 6
var new_dtheta = dtheta + (k1[1] + 2 * k2[1] + 2 * k3[1] + k4[1]) / 6
return [new_theta, new_dtheta]
}
var setup = function() {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.strokeStyle = "black";
lastTime = new Date();
requestAnimFrame(loop);
}
var loop = function() {
var timeMs = (new Date()).getTime();
var deltaT = (timeMs - lastTime.getTime()) / 1000;
/*
When switching away from the window,
requestAnimationFrame is paused. Switching back
will give us a giant deltaT and...