xxxxxxxxxx
102
let angle;
let angleV = 0;
let angleA = 0;
let bob;
let len;
let origin;
let gravity = 9.81;
//Timing pendulum params
let minX = Infinity;
let maxX = -Infinity;
let previousTime = 0;
let goingLeft = false;
let averagePeriod = 0;
let countPeriods = 0;
let pi = 0;
let previousFrameTime = (new Date()).getTime();
function setup() {
createCanvas(600, 400);
//Pendulum parameters (in meters)
origin = createVector(3,0);
bob = createVector();
len = 3;
angle = -PI/20;
previousFrameTime = (new Date()).getTime();
previousTime = (new Date()).getTime();
}
function draw() {
//Time between current and previous frame
let currentFrameTime = (new Date()).getTime();
let deltaFrameTime = (currentFrameTime - previousFrameTime) / 1000;
//Calculate force on pendulum
let force = - gravity * sin(angle);
//Angular acceleration
angleA = force / len;
//New angular velocity
angleV += angleA * deltaFrameTime;
//New angle
angle += angleV * deltaFrameTime;
//Calculate bob position based on angle
bob.x = origin.x + len * sin(angle);
bob.y = origin.y + len * cos(angle);
//Time the period
if (goingLeft) {
if (bob.x < minX && goingLeft) {
minX = bob.x;
} else {
minX = Infinity;
goingLeft = false;
//Calculate current period
let currentTime = previousFrameTime;
let period = (currentTime - previousTime)/1000;
previousTime = currentTime;
//Calculate average period
countPeriods++;
averagePeriod = (averagePeriod * (countPeriods-1) + period)/ countPeriods;
//Calculate PI
pi = averagePeriod / 2 / (sqrt(len / gravity));
}
} else {
if (bob.x > maxX) {
maxX = bob.x;
} else {
goingLeft = true;
maxX = -Infinity;
}
}
previousFrameTime = currentFrameTime;
//Draw everything
background(0);
stroke(255);
strokeWeight(4);
fill(127);
line(origin.x*100, origin.y*100, bob.x*100, bob.y*100);
circle(bob.x*100, bob.y*100, 32);
noStroke();
fill(255);
text("Period: " + averagePeriod + " seconds", 20, 20);
text("Pi: " + pi, 20, 40);
}