### Author Topic: Collision 2D  (Read 162057 times)

#### Fu-Kwun Hwang

• Hero Member
•     • • Posts: 3062 ##### Collision 2D
« on: November 19, 2004, 10:09:24 am »
Registed user can get files related to this applet for offline access.
Problem viewing java?Add http://www.phy.ntnu.edu.tw/ to exception site list

The following is a simulation for elastic collision which means that
1. the momentum is conserved: \$m_1vec{V_1}+m_2vec{V_2}=m_1vec{V'_1}+m_2 vec{V'_2}\$ where \$m_1,m_2\$ are mass for each object, \$vec{V_1},vec{V_2}\$ are velocity vectors before collision,\$vec{V'_1},vec{V'_2}\$ are velocity vectors after collision.
2. the total energy is conserved: \$frac{1}{2}m_1vec{V_1}^2+frac{1}{2}m_2vec{V_2}^2=frac{1}{2}m_1vec{V'_1}^2+frac{1}{2}m_2vec{V'_2}^2\$
For collision in 2D, there are four unknow, however, there are only three equations. Because the contact point is missing in the above equations.
To solve the above problem, we can break 2D collision problem into two 1D collision problem once we know the contact point (when collision happened).
We use x-y coordinate to describe the position of those two balls before and after the collision.
At the time when two balls just in contact with each other, we can choose a new coordinate system:
1. direction from center of mass of \$m_1\$ to center of mass of \$m_2\$: The interaction forces bwteen those two balls during collision is limited to this direction. It become a 1D collision problem in this direction.
2. direction which is perpendicular to the above direction: Assume there is no friction between those two balls, no rotation effect to be considered, then the velocity component for those two balls in this direction will not be changed when collision happened (Because the interaction force dose not have component in this direction).

This simulation shows the physics of two ball collide in 2D (without any rotation motion).
What can be changed:
• The sliders on either side change the vertical position of each ball

• mass(m) and initial horizontal velocity(vx) can be adjusted with slider bar

• Use mouse click and drag to change the position (click near the center of the ball) or the velocity vector (click near the arrow)

• check out the "paused when collide" checkbox to show more detail process during collision,
Click mouse in the area to play it again

Physics processes:
1. when two ball meets, the program shows two components of the velocity for each ball (along the line connect two ball and perpendicular to it)

2. Interaction (force) between balls is along the line connect two balls

3. Velocitys perpendicular to connection line are not changed (No force/interaction in that direction)

4. The rest of the problem is similar to 1D collision problem for ball with velocity along the line

5. Because this is a 2D simulation, so the radius is proportional to the square root of the mass to keep the same density (for those balls).

You need to understand conservation of momentum and conservation of energy.
The velocity of two objecs after collision (V1',V2')can be calculated from velocity before collisions (V1,V2) and mass of two objects (m1,m2).

V1'= (m1-m2)*V1/(m1+m2) + 2*m2*V2/(m1+m2)= (m1V1+m2V2)/(m1+m2)+(V2-V1)*m2/(m1+m2)=Vcm+(V2-V1)*m2/(m1+m2);

V2'=2*m1*V1/(m1+m2)+(m2-m1)*V2/(m1+m2)=(m1V1+m2V2)/(m1+m2)+(V1-V2)*m1/(m1+m2)=Vcm+(V1-V2)*m1/(m1+m2);

Where Vcm=(m1V1+m2V2)/(m1+m2);
Before the collision, the velocity of m1 relative to Vcm is
V1-Vcm=V1-(m1V1+m2V2)/(m1+m2)=m2(V1-V2)/(m1+m2)
compare it with the second term in V1'

If m1=m2 then V1'=V2, V2'-V1 ;
it means that both particles just exchange velocity.
If m1>> m2 then V1' ? V1 ; V2'? 2V1+V2;
i.e. If a heavy car hit you with velocity V1=50km/hr , you will fly out with velocity 2V1=100km/hr.
If m1<< m2 then V1' ? -V1+2V2 ; V2'? V2;
i.e. If a small ball hit a wall (V2=0),then the ball will be bounced back (same magnitude,oppositive direction).

For collision 2D, the trick is to transform it into collision 1D problem:
In the direction of red arows, and another direction normal to red arrows (i.e. direction of green arrows).
If friction is not considered (which will cause both balls to rotate due to friction force),
Then green arrow velocity is not changed after the collision because there is no force in that direction.
And collision in red arrow direction is 1D collision problem, so you can use the above equation.
However, you need to calculate the component of velocity in red arrow direction. (This you need to understand the meaning of inner product -- mathematic operation). Registed user can get files related to this applet for offline access.
Problem viewing java?Add http://www.phy.ntnu.edu.tw/ to exception site list

• Newbie
• • Posts: 2 ##### Re: Collision 2D
« Reply #1 on: August 13, 2007, 05:34:03 pm »
Hello Professor,

I am trying to develop a simple table/board game and was looking for some "good" physics to apply to the game - like -angle, velocity, friction, collision etc.

I got a fair idea from your other articles, but this one is close enough to what i was looking for.

Is it possible for you to share the source code for this one so that I can extract the required algoriths from it?

Thanks.

#### Fu-Kwun Hwang

• Hero Member
•     • • Posts: 3062 ##### Re: Collision 2D
« Reply #2 on: August 13, 2007, 07:09:04 pm »
Registed user can get files related to this applet for offline access.
Problem viewing java?Add http://www.phy.ntnu.edu.tw/ to exception site list

-*-

Here is a modified version of the above simualtion:

Registed user can get files related to this applet for offline access.
Problem viewing java?Add http://www.phy.ntnu.edu.tw/ to exception site list

• Newbie
• • Posts: 2 ##### Re: Collision 2D
« Reply #3 on: August 14, 2007, 12:56:08 pm »
Thank you  very much. I'll try and see how I can get best out of it. #### goldentrash

• Newbie
• • Posts: 1 ##### Re: Collision 2D
« Reply #4 on: October 17, 2007, 04:12:11 am »
Hello Profesor
I know it's a bit rude but..I have a little time to give my teacher working java application of 2d collision of 2 balls inside the square fence and I need the source code..please if you can,help me.I'm a novice in java..so that's why I have a problem.
daniel
« Last Edit: October 17, 2007, 04:31:49 am by goldentrash »

#### Fu-Kwun Hwang

• Hero Member
•     • • Posts: 3062 ##### Re: Collision 2D
« Reply #5 on: October 17, 2007, 09:29:01 am »
You can also "load ejs as signed applet" to view the code in EJS and recompile it or generate java source code from it.

#### Chetmun

• Newbie
• • Posts: 6 ##### Re: Collision 2D
« Reply #6 on: November 10, 2008, 08:39:34 am »
Thank you for sharing your work on this 2D collision stuff. It was very clear and I was able to implement it quickly into my Java program. I have tested the technique with various parameters: 2 balls to multiple balls, different sizes, different initial trajectories, and different initial velocities. It worked well from the very beginning thanks to your clear example.

However, (didn't you know that was coming ) I am having a bit of a problem. The balls seem to stick sometimes and even bounce off in odd directions. Sometimes the velocities increase at unexpected levels.

I put a test after the new locations and velocities have been calculated to see if the values were NaN's according to Java. In those cases I did not update the locations or velocities and the balls would overlap for a period of time.

I am assuming this is some kind of math precision issue. I have kept all variables at the level of Java's "double". Is there some kind of technique you employ to prevent this sort of behavior? Perhaps there's a flaw in my processing of all the balls. I "move" them all, then check each one against each other (only once, no redundancy) adjusting the locations and velocities according to your example.

Thanks in advance for any help.

#### Fu-Kwun Hwang

• Hero Member
•     • • Posts: 3062 ##### Re: Collision 2D
« Reply #7 on: November 11, 2008, 09:55:27 pm »
1. The situation will happen if you did not move the ball back to the time where two balls just collide. (If you just checked if those two ball collide with each other).
2. If you did the time correction. The situation you have descrbed might happened if the velocity was set too large or the time step is too large. And it also possible that you might have three balls collide at the same time (within your simulation time step).  However, the program only take care of two balls collision. Reduced the time step might help.

Because I do not know how it was implemented in your program and what are the initial condition for your case, I can not say any more.

#### Chetmun

• Newbie
• • Posts: 6 ##### Re: Collision 2D
« Reply #8 on: November 12, 2008, 02:18:15 am »
Thanks for your reply. I am enclosing my code for your perusal. I think I have included everything I've seen from your posts. In other words, I believe I have "moved" the balls back in time properly. I see your point about the velocities possibly being too large. I will experiment with that. The initial directional velocities are randomly between 13 and 20 per time step. The radii are randomly between 15 and 50. Even though I have multiple balls moving simultaneously, the situation arises with 2-ball collisions and no other ball nearby. Perhaps you can spot something I missed.

private boolean collision(Circle c1, Circle c2)
{
double x1 = c1.getX(), y1 = c1.getY();
double x2 = c2.getX(), y2 = c2.getY();

double dx = x2 - x1;
double dy = y2 - y1;
double d = Math.sqrt(dx*dx + dy*dy);

if(d <= r1 + r2)
{
double vx1 = c1.getXdir(), vy1 = c1.getXdir();
double vx2 = c2.getXdir(), vy2 = c2.getXdir();
double mass1 = c1.getMass(), mass2 = c2.getMass();

// velocity in the direction of (dx, dy)
double vp1 = (vx1*dx + vy1*dy) / d;
double vp2 = (vx2*dx + vy2*dy) / d;

// collision should have happened dt before
double dt = (r1 + r2 - d) / (vp1 - vp2);

// move the circles backward in time
x1 -= vx1 * dt;
y1 -= vy1 * dt;
x2 -= vx2 * dt;
y2 -= vy2 * dt;

// new collision calculations at impact
dx = x2 - x1;
dy = y2 - y1;
d = Math.sqrt(dx*dx + dy*dy);

// unit vector in the direction of the collision
double ax = dx/d;
double ay = dy/d;

// projection of the velocities in these axes
double va1 =  vx1*ax + vy1*ay;
double vb1 = -vx1*ay + vy1*ax;
double va2 =  vx2*ax + vy2*ay;
double vb2 = -vx2*ay + vy2*ax;

// calculate new velocity after collision
double ed = 1;
double vaP1 = va1 + (1 + ed) * (va2 - va1) / (1 + mass1/mass2);
double vaP2 = va2 + (1 + ed) * (va1 - va2) / (1 + mass2/mass1);

// undo projections
vx1 = vaP1*ax - vb1*ay;
vy1 = vaP1*ay + vb1*ax;
vx2 = vaP2*ax - vb2*ay;
vy2 = vaP2*ay + vb2*ax;

// move time dt forward
x1 += vx1 * dt;
y1 += vy1 * dt;
x2 += vx2 * dt;
y2 += vy2 * dt;

// update locations and velocities
if (!Double.isNaN(x1)) c1.setX(x1);
if (!Double.isNaN(y1)) c1.setY(y1);
if (!Double.isNaN(x2)) c2.setX(x2);
if (!Double.isNaN(y2)) c2.setY(y2);
if (!Double.isNaN(vx1)) c1.setXdir(vx1);
if (!Double.isNaN(vy1)) c1.setYdir(vy1);
if (!Double.isNaN(vx2)) c2.setXdir(vx2);
if (!Double.isNaN(vy2)) c2.setYdir(vy2);

return true;
}
else
return false;
}

#### Chetmun

• Newbie
• • Posts: 6 ##### Re: Collision 2D
« Reply #9 on: November 12, 2008, 10:02:13 am »
P.S. I did notice an error in my code regarding the retrieval of the y-velocities and have fixed that to no avail. I'm going to try moving the balls further ahead in time to where they are no longer colliding. I think that is the problem. Not sure how to calculate that but it seems the thing to do.

#### Chetmun

• Newbie
• • Posts: 6 ##### Re: Collision 2D
« Reply #10 on: November 12, 2008, 10:19:57 am »
To interested parties, I changed the if(d <= r1 + r2) to while(d <= r1 + r2) and it seems to work a little better. The balls don't seem to stick together. However, I'm still getting some odd jumps in velocity and the deflection angles look wrong sometimes.

#### lookang

• Hero Member
•     • • Posts: 1772
• http://weelookang.blogspot.com ##### Re: Collision 2D
« Reply #11 on: November 12, 2008, 05:26:20 pm »

upload your xml file if suits #### Fu-Kwun Hwang

• Hero Member
•     • • Posts: 3062 ##### Re: Collision 2D
« Reply #12 on: November 12, 2008, 11:47:59 pm »
Quote
The initial directional velocities are randomly between 13 and 20 per time step. The radii are randomly between 15 and 50.

It seems that your time step is too large (or velocity is too large).
Because you have particle moves 13-20 unit per time step, however, the radii are between 15-50.
So it is possible that the particle could move past half of the size of the particle.
However,  an approximation was made when I calculate the time particles really collide. (I have assumed that when we detect particle collide, the overlap distance is much small that their radii.
I think your problem will not occur again if you change velocity to 1.3-2.0

#### Chetmun

• Newbie
• • Posts: 6 ##### Re: Collision 2D
« Reply #13 on: November 13, 2008, 05:06:34 am »
Thank you, I will experiment with a reduction in the velocities though I am not convinced that will help regarding the "jumpiness" I am seeing. I have taken the randomness out and am just manipulating 3 circles of equal size but I still see the circles move in unexpected ways occasionally upon collision, ie. the wrong angle or with a much larger velocity. I am curious about the approximation you mention. How is it an approximation? I wonder if making it more exact would help.

#### Fu-Kwun Hwang

• Hero Member
•     • • Posts: 3062 ##### Re: Collision 2D
« Reply #14 on: November 13, 2008, 03:01:09 pm »
Quote
double vx1 = c1.getXdir(), vy1 = c1.getXdir();
double vx2 = c2.getXdir(), vy2 = c2.getXdir();

Please check out how you calculate vy1 and vy2!