xxxxxxxxxx
81
class Ball {
constructor(x, y) {
this.pos = createVector(x, y);
this.vel = createVector(0, 0);
this.r = BALL_RADIUS;
}
show() {
noStroke();
fill(255);
ellipse(this.pos.x, this.pos.y, this.r);
}
update() {
if (this.vel.mag() < 0.1) this.vel = createVector(0, 0);
if (this.vel.mag() < 2) this.vel.mult(0.98);
this.vel.mult(0.98);
this.pos.add(this.vel.copy());
}
static transposeMatrix2x2(matrix) {
return [matrix[0], matrix[2], matrix[1], matrix[3]];
}
static createRotationMatrixFromAngle(theta) {
let c = Math.cos(theta);
let s = Math.sin(theta);
return [c, s, -s, c];
}
static matrix2x2MultiplyVector2(matrix, vector) {
let MatrixRow1Vec = createVector(matrix[0], matrix[1]);
let MatrixRow2Vec = createVector(matrix[2], matrix[3]);
return createVector(vector.dot(MatrixRow1Vec), vector.dot(MatrixRow2Vec));
}
static collisionReboundSingleAxis(particle1, particle2) {
let collisionForce = particle2.vel.x;
return collisionForce;
}
static billiardCollision(particle1, particle2) {
let distVec = particle2.pos.copy().sub(particle1.pos);
// calculate the angle
let angle = Math.atan2(distVec.y, distVec.x);
let mat = Ball.createRotationMatrixFromAngle(angle);
let inverseRotation = Ball.transposeMatrix2x2(mat);
// rotate the velocities of the particles so that the collision
// happens on a single axis (x-axis) rather than 2 axes
let vel1 = Ball.matrix2x2MultiplyVector2(mat, particle1.vel.copy());
let vel2 = Ball.matrix2x2MultiplyVector2(mat, particle2.vel.copy());
// collision reacton
let vxTotal = vel1.x - vel2.x;
vel1.x = Ball.collisionReboundSingleAxis(particle1, particle2, vel1, vel2);
vel2.x = vxTotal + vel1.x;
// particles often get stuck if they are going the same direction
// a dot product greater than zero means they are going the same direction
// reversing the velocity of one of the particles helps to keep them from getting stuck
if (vel1.dot(vel2) > 0) vel1.x *= -1;
// position adjustment
let particle1Adjustment = Ball.matrix2x2MultiplyVector2(inverseRotation, createVector(0, 0));
particle1.pos = particle1.pos.copy().add(particle1Adjustment);
particle2.pos = particle1.pos.copy().add(distVec);
// rotate velocity back
let reboundVelocity1 = Ball.matrix2x2MultiplyVector2(inverseRotation, vel1);
let reboundVelocity2 = Ball.matrix2x2MultiplyVector2(inverseRotation, vel2);
particle1.vel = reboundVelocity1;
particle2.vel = reboundVelocity2;
}
}