Original Post
Hi all, So I'm trying to do some collision physics and I'm currently working with a circle adn a rectangle. I also want to preserve kinetic energi after collision so the two objects have finite masses. When the circle/ball collides with one of the four sides of the rectangle everything seems to be fine. I do have some problem with the corners though. Here's how I was thinking of solving this: When the circle touches a corner, I use the line between the corner and the middle of the circle to create a normal. Then I use the velocity vector for the collision, decompose it so I get a component along the normal and one perpendicular to it. I do the same with the velocity vector for the rectangle and then I use the two vector components which lie along the normal and use them to collide the two objects as you would with a one dimensional collision. I think this should give a somewhat realistic bounce when the two objects collide, but what I fear is that my code is really messed up. So I would love if someone has the time and take a look at it and give me some feedback what could be wrong. I've been sitting with this for quite some time and you will notice that the further down into the code you get, the more messed up it is. But it's still just a sketch so I blame it on that. I just want the damn collisions to work =) Here's the code for when the ball collides with the top left corner of the rectangle. I think I basically have the same code for all the corners except for when two/three lines where the normal is calculated (since x_pos, y_pos are in the middle of the rectangle). I also got an applet up with this code, you can find it here and see what happens when collisions occur. If you reload the page it should generate new speeds and dimensions for the objects. If you don't wanna look at the applet what happens is that the ball kinda (sometimes) gets stuck inside the rectangle, when it collides with a corner, of course. I think it might have something to do that all the trigonometry with the angles loses what quadrant the angle should be in, or something. Well any help would be greatly appreciated. And the code...
//top left cornet
if (getDistance(ball_x, ball_y, rect_x-rect_w/2, rect_y-rect_h/2) < ball_r)
{
//change color to indicate collision
ball.setColor(Color.blue);
//stupid variables for the dot product
double pt1 = ball_vx;
double pt2 = ball_vy;
double pt3 = (rect_x - rect_w/2) - ball_x; //this is the collision normal, a line form the middle of the circle to the corner
double pt4 = (rect_y - rect_h/2) - ball_y;
//dot product to find angle between ball's velocity vector and collision normal
double ai = ((pt1*pt3) + (pt2*pt4)) / ((Math.sqrt(pt1*pt1+pt2*pt2)) * (Math.sqrt(pt3*pt3+pt4*pt4)));
double i = Math.acos(ai);
//rotate the vector (OBS. might need some tweaking for the different cases if something shows up)
/*double xp = Math.cos(2*i)*ball_vx - Math.sin(2*i)*ball_vy; //detta ska också ändras för andra fall
double yp = Math.sin(2*i)*ball_vx + Math.cos(2*i)*ball_vy;
//set final velocity vector
ball.setVelX(xp);
ball.setVelY(yp);*/
//this is the velocity vector for the ball projected on the normal
double bcv = ball_vec * Math.cos(i);
//use dot product to find the angle between the rect's velocity vector and the normal
pt1 = rect_vx;
pt2 = rect_vy;
double air = ((pt1*pt3) + (pt2*pt4)) / ((Math.sqrt(pt1*pt1+pt2*pt2)) * (Math.sqrt(pt3*pt3+pt4*pt4)));
double ir = Math.acos(air);
//the rect's velocity vector projected on the normal
double rcv = rect_vec * Math.cos(ir);
//calculate the velocities after collision
double ball_final = bcv * ((ball_m-rect_m)/(ball_m+rect_m)) + rcv * ((2*rect_m)/(ball_m+rect_m));
double rect_final = bcv * ((2*ball_m)/(ball_m+rect_m)) - rcv * ((ball_m-rect_m)/(ball_m+rect_m));
//now we have the two final vectors on the normal. these need to be used together with the remaining components from the initial velocity vectors
//to get the final velocity vectors This should be correct in theory, I hope, but I fear the code bellow is messed up.
//first the ball
double remaining_component = Math.sin(i) * ball_vec; //get the remaining component from the initial velocity vector (i.e. the one not colliding)
double ball_f = Math.sqrt(remaining_component*remaining_component + ball_final*ball_final); //the final velocity vector
//calculate the new angle between the new velocity vector and the normal
double new_i = Math.atan(ball_final / remaining_component);
//calculate angle between normal and x-axis
double norm_a = Math.atan(pt4/pt3);
//angle between velocity vector and x-axis
double final_a = norm_a - new_i; //this i'm very uncertain about
//set the speeds
ball.setVelX(ball_f * Math.cos(final_a));
ball.setVelY(ball_f * Math.sin(final_a));
//now the rectangle
remaining_component = Math.sin(ir) * rect_vec; //get the remaining component from the initial velocity vector (i.e. the one not colliding)
double rect_f = Math.sqrt(remaining_component*remaining_component + rect_final*rect_final); //the final velocity vector
//calculate the new angle between the new velocity vector and the normal
new_i = Math.atan(rect_final / remaining_component);
//angle between velocity vector and x-axis
final_a = norm_a + new_i;
//set the speeds
rect.setVelX(rect_f * Math.cos(final_a));
rect.setVelY(rect_f * Math.sin(final_a));
}