Hey everyone. Not sure if you have found this already but I am in the process of creating a snooker game in canvas. My collision detection / handling of the balls is as follows. It's using trig at the moment but could be optimised using some vector math instead. Anyway, you can see the progress with it in action -> here
This loop runs in my animate function:
// checks if the any of the balls have collided with each other
for(i=0;i<ballArray.length;i++)
{
for(j=i;j<ballArray.length;j++)
{
if(j != i)
{
if( Math.pow((ballArray[j].x - ballArray[i].x),2) + Math.pow((ballArray[j].y - ballArray[i].y),2) <= (ballArray[i].radius + ballArray[j].radius) * (ballArray[i].radius + ballArray[j].radius))
{
dx = ballArray[i].x - ballArray[j].x;
dy = ballArray[i].y - ballArray[j].y;
// collision angle is often refered to as the greek character 'phi'
phi = Math.atan2(dy, dx);
magnitude_1 = Math.sqrt(ballArray[i].vx * ballArray[i].vx + ballArray[i].vy * ballArray[i].vy);
magnitude_2 = Math.sqrt(ballArray[j].vx * ballArray[j].vx + ballArray[j].vy * ballArray[j].vy);
direction_1 = Math.atan2(ballArray[i].vy, ballArray[i].vx);
direction_2 = Math.atan2(ballArray[j].vy, ballArray[j].vx);
new_xspeed_1 = magnitude_1 * Math.cos(direction_1 - phi);
new_yspeed_1 = magnitude_1 * Math.sin(direction_1 - phi);
new_xspeed_2 = magnitude_2 * Math.cos(direction_2 - phi);
new_yspeed_2 = magnitude_2 * Math.sin(direction_2 - phi);
final_xspeed_1 = ((ballArray[i].mass - ballArray[j].mass) * new_xspeed_1 + (ballArray[j].mass + ballArray[j].mass) * new_xspeed_2) / (ballArray[i].mass + ballArray[j].mass);
final_xspeed_2 = ((ballArray[i].mass + ballArray[i].mass) * new_xspeed_1 + (ballArray[j].mass - ballArray[i].mass) * new_xspeed_2) / (ballArray[i].mass + ballArray[j].mass);
final_yspeed_1 = new_yspeed_1;
final_yspeed_2 = new_yspeed_2;
ballArray[i].vx = Math.cos(phi) * final_xspeed_1 + Math.cos(phi + Math.PI / 2) * final_yspeed_1;
ballArray[i].vy = Math.sin(phi) * final_xspeed_1 + Math.sin(phi + Math.PI / 2) * final_yspeed_1;
ballArray[j].vx = Math.cos(phi) * final_xspeed_2 + Math.cos(phi + Math.PI / 2) * final_yspeed_2;
ballArray[j].vy = Math.sin(phi) * final_xspeed_2 + Math.sin(phi + Math.PI / 2) * final_yspeed_2;
}
}
}
}