With the help of the Stack Overflow community I\'ve written a pretty basic-but fun physics simulator.
After some trial and error, I used this document's method for 2D collisions : https://www.vobarian.com/collisions/2dcollisions2.pdf (that OP linked to)
I applied this within a JavaScript program using p5js, and it works perfectly. I had previously attempted to use trigonometrical equations and while they do work for specific collisions, I could not find one that worked for every collision no matter the angle at the which it happened.
The method explained in this document uses no trigonometrical functions whatsoever, it's just plain vector operations, I recommend this to anyone trying to implement ball to ball collision, trigonometrical functions in my experience are hard to generalize. I asked a Physicist at my university to show me how to do it and he told me not to bother with trigonometrical functions and showed me a method that is analogous to the one linked in the document.
NB : My masses are all equal, but this can be generalised to different masses using the equations presented in the document.
Here's my code for calculating the resulting speed vectors after collision :
class TBall {
constructor(x, y, vx, vy) {
this.r = [x, y];
this.v = [0, 0];
}
}
function collision(ball1, ball2) {
n = [ (ball1.r)[0] - (ball2.r)[0], (ball1.r)[1] - (ball2.r)[1] ];
un = [n[0] / vecNorm(n), n[1] / vecNorm(n) ] ;
ut = [ -un[1], un[0] ];
v1n = dotProd(un, (ball1.v));
v1t = dotProd(ut, (ball1.v) );
v2n = dotProd(un, (ball2.v) );
v2t = dotProd(ut, (ball2.v) );
v1t_p = v1t; v2t_p = v2t;
v1n_p = v2n; v2n_p = v1n;
v1n_pvec = [v1n_p * un[0], v1n_p * un[1] ];
v1t_pvec = [v1t_p * ut[0], v1t_p * ut[1] ];
v2n_pvec = [v2n_p * un[0], v2n_p * un[1] ];
v2t_pvec = [v2t_p * ut[0], v2t_p * ut[1] ];
ball1.v = vecSum(v1n_pvec, v1t_pvec); ball2.v = vecSum(v2n_pvec, v2t_pvec);
}