You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

100 lines
2.5 KiB

const g = 9.81
class NPendulum {
pendula: Pendulum[] = []
constructor(lengths, masses, startRad, color) {
switch (lengths.length) {
case 1:
this.pendula.push(new Pendulum(lengths[0], masses[0], startRad, color));
break;
case 2:
let p1 = new Pendulum(lengths[0], masses[0], startRad, color);
let p2 = new Pendulum(lengths[1], masses[1], startRad, color);
p1.calcAcc = function(pendula){
let p2 = pendula[1];
return -g / this.l * p.sin(this.rad) - p2.l * p2.m / this.l / (this.m + p2.m)
* (p.cos(this.rad - p2.rad) * p2.acc + p.sin(this.rad - p2.rad) * p.pow(p2.vel, 2));
}
p2.calcAcc = function (pendula){
let p1 = pendula[0];
return -g / this.l * p.sin(this.rad) - p1.l / this.l
* (p.cos(p1.rad - this.rad) * p1.acc - p.sin(p1.rad - this.rad) * p.pow(p1.vel, 2));
}
this.pendula.push(p1, p2);
break;
}
this.pendula[0].origin = p.createVector(0, 0);
}
updateOrigins(){
this.pendula.forEach((p, i) => {
if (i > 0){
let before = this.pendula[i - 1];
p.origin = p5.Vector.add(before.origin, before.pos);
}
});
}
update(h){
this.pendula.forEach((p, i) => {
p.update(h, this.pendula);
});
this.updateOrigins();
}
draw(){
this.pendula.forEach(p => p.draw());
}
}
class Pendulum {
l: number
m: number
acc: number = 0
vel: number = 0
rad: number
origin: p5.Vector
color: p5.Color
constructor(l, m, rad, color) {
this.l = l;
this.m = m;
this.rad = rad;
this.color = color;
}
calcAcc(pendula){
return -g / this.l * p.sin(this.rad);
}
update(h, pendula = []){
this.acc = this.calcAcc(pendula);
this.vel += this.acc * h;
this.rad += this.vel * h;
}
draw(){
let pos = this.pos;
p.push();
p.translate(this.origin);
p.stroke(this.color);
p.strokeWeight(3);
p.line(0, 0, pos.x, pos.y);
p.ellipse(pos.x, pos.y, this.m * 5, this.m * 5);
p.pop();
}
get pos(){
return p5.Vector.mult(p.createVector(p.sin(this.rad), p.cos(this.rad)), this.l);
}
}