NTNUJAVA Virtual Physics LaboratoryEnjoy the fun of physics with simulations! Backup site http://enjoy.phy.ntnu.edu.tw/ntnujava/
December 12, 2017, 12:18:45 am

"Life is the beaty of art, heart, and humanity."...Wisdom

 Pages: 1 2 3 [4] 5 6   Go Down
 Author Topic: 2D Collision  (Read 459680 times) 0 Members and 1 Guest are viewing this topic. Click to toggle author information(expand message area).
saeky123
Newbie

Offline

Posts: 1

 « Embed this message Reply #90 on: July 19, 2008, 06:24:28 pm »

Hi professor, and thanks for your help...
I have followed your post. But I have a question, have you ever worked on  collision in 2d with 3 or more balls. I means that collision with more than 2 balls. In this case, I can't use d for distance between 2 balls. I wondered if I use a matrix that store all the boundary of the balls. So that, when the balls collide, the matrix will meet together. Or, maybe, I have to store many d for distance between balls. For example, if I have 3 balls, I use d1 for distance between ball 1 and 2, d2( for ball 2 and 3) and d3(of course, distance between ball 1 and 3).

Can you give me any suggestions?
 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #91 on: July 19, 2008, 11:04:43 pm »

There are several examples of many particles collide with each other at this web site. You can check out those EJS examples and find out how I did it.
Besically, it can be done in the following way:
Suppose you have defined a function to take care collision between two particles:

public function collision(int i,int j, double m[],double x[],double y[], double vx[],double vy[]){
// the code should take care of the collision between particle i, and particle j
}

Then for collision between n particles : you can have the following loops to deal with all the collisions
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
collision(i,j,m,x,y,vx,vy);
}
}
 Logged
venice
Newbie

Offline

Posts: 1

 « Embed this message Reply #92 on: August 27, 2008, 11:23:32 am »

great article ..

but there is a error in post 7..where this statement
dt =(r1+r2-d)/(vp1+vp2) should be as dt =(r1+r2-d)/(vp1-vp2)...

and i wonder if it's possible to do this without using double..

many calculation like division in this method come out many double typed value..

coz i intend to do this collision method in my mobile phone game
 « Last Edit: August 27, 2008, 11:25:58 am by venice » Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #93 on: August 27, 2008, 04:35:20 pm » posted from:Taipei,T'ai-pei,Taiwan

The equation is corrected. Thank you!
It is possible to find way to work with integer only but the result will has some error.
It it true that there is no double type in programming for mobile device? How could that be
 Logged
ArdTraveller
Newbie

Offline

Posts: 12

 « Embed this message Reply #94 on: January 12, 2009, 12:12:23 pm »

Sir, like how you've provided the complete and runnable source code for this 2D collision can u pleaz provide the similar type of code for the 2D Collision the new one, thx
 Logged
amol
Newbie

Offline

Posts: 4

 « Embed this message Reply #95 on: January 13, 2009, 09:16:30 pm »

Hi professor,

Can u please elaborate these two lines with respect to ur post#7:

// New velocities in these axes (after collision): ed<=1,  for elastic collision ed=1
double vaP1=va1 + (1+ed)*(va2-va1)/(1+mass1/mass2);
double vaP2=va2 + (1+ed)*(va1-va2)/(1+mass2/mass1);
// Undo the projections
vx1=vaP1*ax-vb1*ay;  vy1=vaP1*ay+vb1*ax;// new vx,vy for ball 1 after collision
vx2=vaP2*ax-vb2*ay;  vy2=vaP2*ay+vb2*ax;// new vx,vy for ball 2 after collision
 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #96 on: January 13, 2009, 09:43:54 pm »

I hope you understand that we have transfer 2D collisions to two 1D collision.
Do you fully understand the above part?

// New velocities in these axes (after collision): ed<=1,  for elastic collision ed=1
double vaP1=va1 + (1+ed)*(va2-va1)/(1+mass1/mass2);
double vaP2=va2 + (1+ed)*(va1-va2)/(1+mass2/mass1);

The above equations calculate velocity for those two particle just after the collision.

Do you konw/unstand how to calculate 1D elastic collision problem?
If you set ed=1, the above equation will be the same as equations for 1D elastic collision.

Then,we need to move back to our original x-y coordinate.
// Undo the projections
vx1=vaP1*ax-vb1*ay;  vy1=vaP1*ay+vb1*ax;// new vx,vy for ball 1 after collision
vx2=vaP2*ax-vb2*ay;  vy2=vaP2*ay+vb2*ax;// new vx,vy for ball 2 after collision

Please write down the physics you know about collision in detail, so that we can focus on your problem!
 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #97 on: January 14, 2009, 04:46:44 pm » posted from:Taipei,T'ai-pei,Taiwan

Due to so many requests from the users, source code for this applet is distributed with the ZIP files you will receive if you click get file for offline use button.
 Logged
Question
Newbie

Offline

Posts: 10

 « Embed this message Reply #98 on: January 15, 2009, 09:54:38 am »

 Logged
Question
Newbie

Offline

Posts: 10

 « Embed this message Reply #99 on: January 15, 2009, 10:00:33 am »

Sir, thx for the code for this applet, could u help me sir, at what part of the could can i change so that there is a slider in order ro change the mass and velocity of the balls and what code to enable me to drag the ball and change the direction of the ball,similar to the Collision 2D or the latest one u created,thx
 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #100 on: January 15, 2009, 10:52:19 am » posted from:Taipei,T'ai-pei,Taiwan

This topic is under JDK1.0.2 simulations (1996-2001) board.
Please check out Easy Java Simulations (2001- ) board for simulations created with EJS.

If you just need collison 2D, please check out EJS version cololision2D
 Logged
slenzi
Newbie

Offline

Posts: 3

 « Embed this message Reply #101 on: January 28, 2009, 04:47:37 am »

I'm finding that when the velocity of the two balls in the Y axis is 0 (the balls collide head on) they stick together. I'm just using your code and don't have a full understanding of it. Basically just checking to see if I'm doing something wrong. It works just fine if the balls are moving in both axis.

I'm finding that ddt = 0 in this case and its messing it up.

Code:

// Velocity of ball b1 in direction of ball b2
double vab1 = (b1.getVelocityX() * (dx/distance)) + (b1.getVelocityY() * (dy/distance));
// Velocity of ball b2 in direction of ball b1
double vab2 = (b2.getVelocityX() * (dx/distance)) + (b2.getVelocityY() * (dy/distance));
// The collision will have actually happened at ddt before we detect
// distance <= (r1 + r2) collision.
double ddt = (r1 + r2 - distance) / (vab1 - vab2);

// using ddt, move the balls backwards so they don't overlap. Now the distance
// between the two balls should be r1 + r2.
b1.setLocation(b1.x -= (b1.velocityX * ddt), b1.y -= (b1.velocityY * ddt));
b2.setLocation(b2.x -= (b2.velocityX * ddt), b2.y -= (b2.velocityY * ddt));

// Unit vector in the direction of the collision
double ax = dx / distance;
double ay = dy / distance;

// Projection of the velocities in these axes
double va1 = b1.velocityX * ax + b1.velocityY * ay;
double vb1 = -b1.velocityX * ay + b1.velocityY * ax;
double va2 = b2.velocityX * ax + b2.velocityY * ay;
double vb2 = -b2.velocityX * ay + b2.velocityY * ax;

// ed=1 for elastic collision, ed<1 for inelastic (material of ball absorbs some energy)
double ed = 1;

// new velocities in these axes (after collision)
double vaP1 = (va1 + (1 + ed ) * (va2 - va1)) / (1 + ((b1.getMass() / b2.getMass())));
double vaP2 = (va2 + (1 + ed ) * (va1 - va2)) / (1 + ((b2.getMass() / b1.getMass())));

// undo projections
b1.setVelocityX((vaP1*ax)-(vb1*ay)); b1.setVelocityY((vaP1*ay)+(vb1*ax));
b2.setVelocityX((vaP2*ax)-(vb2*ay)); b2.setVelocityY((vaP2*ay)+(vb2*ax));

// earlier we moved time backwards one unit, so now we move time forward one unit.
b1.setLocation(b1.x += b1.getVelocityX() * ddt, b1.y += b1.getVelocityY() * ddt);
b2.setLocation(b2.x += b2.getVelocityX() * ddt, b2.y += b2.getVelocityY() * ddt);
);
 Logged
slenzi
Newbie

Offline

Posts: 3

 « Embed this message Reply #102 on: January 28, 2009, 05:02:58 am »

OK, since ddt was 0 I did this and that seems to have corrected the problem.

Code:

if(ddt > 0.0){
b1.setLocation(b1.x -= (b1.velocityX * ddt), b1.y -= (b1.velocityY * ddt));
b2.setLocation(b2.x -= (b2.velocityX * ddt), b2.y -= (b2.velocityY * ddt));
}else{
b1.setLocation(b1.x -= (b1.velocityX), b1.y -= (b1.velocityY));
b2.setLocation(b2.x -= (b2.velocityX), b2.y -= (b2.velocityY));
}

 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #103 on: January 28, 2009, 10:51:17 am »

You did not really solve the problem. You just ignore it.

latest 2D collision created with EJS
starts with head on collision and it work fine.

I think the problem might be due to the condition you check for the collision occurred.
May be you have some other bug in the code.

P.S. The above code you copy from was not my original code.
Please check out my original message

 Logged
slenzi
Newbie

Offline

Posts: 3

 « Embed this message Reply #104 on: January 29, 2009, 12:15:05 am » posted from:Somerville,Massachusetts,United States

Thanks for the reply. I think I found the problem. I removed the if ddt > 0 and it seems to work.

You did not really solve the problem. You just ignore it.

latest 2D collision created with EJS
starts with head on collision and it work fine.

I think the problem might be due to the condition you check for the collision occurred.
May be you have some other bug in the code.

P.S. The above code you copy from was not my original code.
Please check out my original message

 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #105 on: January 29, 2009, 08:05:11 am »

You can change it to if(ddt>=0)
 Logged
ashmpatel
Newbie

Offline

Posts: 1

 « Embed this message Reply #106 on: April 28, 2009, 09:40:53 pm » posted from:Cambridge,Cambridgeshire,United Kingdom

Hi,

I wonder if someone can help with the bit below that I do not understand.
In the bit of the code that works out the velocities ,what is the reason for vb1, vb2.
I can see in the code that it is used to undo the projections but these vb1 & vb2 do not looks like
va1 and va2 -
so for example va1 has vx1*ax and vb1 has -vx1*ay , why ay and not ax as surely you want the reverse of the x velocity but why is ay being used.

Is it possible to have some pics attached to these calculations so I can see what is being worked out ?

Also, in the java code, the method called "advance" is called to work out the new positions.
where in this method is the bit that updates the vecloty of x1 and x2 after a collision has been detected ?
I can see the code works as I have compiled and run it but I do NOT see where the velocities have been set after the collision detection stuff.

double va1=(vx1*ax+vy1*ay), vb1=(-vx1*ay+vy1*ax);
double va2=(vx2*ax+vy2*ay), vb2=(-vx2*ay+vy2*ax);

Due to so many email questions asking for help. I re-wrote this post to include more detail calculation steps:

Assume the radius for two ball are r1 and r2, and the coordinates are (x1,y1) and (x2,y2).
Usually, we calculate the distance between two balls d=sqrt( (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));

The collision should have occurred if d equal r1+r2; // if(d==r1+r2)

However, there is a finite time step dt in the simulation calculation,so most often we would not be able to find the above condition (exact time when two ball real occurred).
So we check if d<= r1+r2; Then we know the collision should have occurred.

The real collision should have occurred before you detected that the distance between two center of the balls d is less than the sum of those two balls r1+r2. (d< r1+r2)

The correct way is to find the time when the two ball really collide with each other.
Suppose the center of those two ball are x1,y2 and x2,y2
dx=x2-x1, dy=y2-y1; d=sqrt(dx*dx+dy*dy);

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

Collision should have happened dt before you have detected r1+r2<d;
and dt =(r1+r2-d)/(vp1-vp2);
and dt =(r1+r2-d)/(vp1-vp2);// the collision should have occurred at t-dt (Actually this is also an approximation).

So you should move those two ball backward
x1-= vx1*dt;
y2 -= vy1*dt;
x2-=vx2*dt;
y2-=vy2*dt;

Now the distance between center of the two balls is d'=r1+r2;

The following code take care of collision:

double dx = x2-x1, dy = y2-y1;
// where x1,y1 are center of ball1, and x2,y2 are center of ball2
double distance = Math.sqrt(dx*dx+dy*dy);
// Unit vector in the direction of the collision
double ax=dx/distance, ay=dy/distance;
// Projection of the velocities in these axes
double va1=(vx1*ax+vy1*ay), vb1=(-vx1*ay+vy1*ax);
double va2=(vx2*ax+vy2*ay), vb2=(-vx2*ay+vy2*ax);
// New velocities in these axes (after collision): ed<=1,  for elastic collision ed=1
double vaP1=va1 + (1+ed)*(va2-va1)/(1+mass1/mass2);
double vaP2=va2 + (1+ed)*(va1-va2)/(1+mass2/mass1);
// Undo the projections
vx1=vaP1*ax-vb1*ay;  vy1=vaP1*ay+vb1*ax;// new vx,vy for ball 1 after collision
vx2=vaP2*ax-vb2*ay;  vy2=vaP2*ay+vb2*ax;// new vx,vy for ball 2 after collision

Because we have move time backward dt, we need to move time forward dt.
so
x1+= vx1'*dt;
y1+=vy1'*dt;
x2+=vx2'*dt;
y2+=vy2'*dt;

Now the distance between two ball will be larger than r1+r2.

If you did not correct the time dt (before you have found collision occurred, you will find balls clutch together. and they don't even let go.

 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #107 on: April 29, 2009, 12:29:44 am » posted from:Taipei,T\'ai-pei,Taiwan

Before collision:
va1, va2 are velocity components in the direction of the line connected between two center of the collided objects.
vb1, vb2 are velocity components in the direction perpendicular to the above line.
after collision:
vap1, vap2 are velocity components in the direction of the line connected between two center of the collided objects.
vb1, vb2 are velocity components in the direction perpendicular to the above line. (if there is no fricion force between collision objects, vb1,vb2 did not change during the collision.)

and the following equation calculate the x,y component for the above vectors
vx1=vaP1*ax-vb1*ay;  vy1=vaP1*ay+vb1*ax;// new vx,vy for ball 1 after collision
vx2=vaP2*ax-vb2*ay;  vy2=vaP2*ay+vb2*ax;// new vx,vy for ball 2 after collision

You need to understand the meaning of inner product in order to understand the above equations.
Please check out scalar product between two vectors
 Logged
seenu
Newbie

Offline

Posts: 2

 « Embed this message Reply #108 on: May 01, 2009, 02:21:28 am »

Hi professor Fu-kwun Hwang,

Firstly i would like to thank you for all your help, this is an excellent place to learn physics.
i have gone through the code and understand most of it.

i have good understand of dot product (scalar product), and its application to find projection of one vector onto the other.
but i am having problem understanding the undo projections
// Undo the projections
vx1=vaP1*ax-vb1*ay;  vy1=vaP1*ay+vb1*ax;// new vx,vy for ball 1 after collision
vx2=vaP2*ax-vb2*ay;  vy2=vaP2*ay+vb2*ax;// new vx,vy for ball 2 after collision

after breaking up the velocity into 2 components ( one onto the direct line of contact of balls , and other as a perpendicular )

How did u arrive at the formula to combine the new velocity with the velocities in perpendicular direction
to arrive at the new vx1 and vy1 for the ball ?
Can you please explain this in detail.

thank you
 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #109 on: May 01, 2009, 08:05:02 am » posted from:Taipei,T\'ai-pei,Taiwan

The vector sum of vap1+vb1 is the velocity for particle/circle 1 after collision, and the sum of vap2+vb2 is the velocity for particle/circle 2 after collision.
We need to break the above vectors into x-component and y-component to add them directly.

(ax,ay)  is the unit vector in the direction connected two objects.
draw a line connect two object, assign the angle between this line and x-axis is θ,
then  cosθ=ax, sin θ=ay
So vap1*ax=vap1*cosθ give x-component of vap1, and vap1*ay give y-component of vap1

Because vb1 and vb2 is in the direction perpendicular to the (ax,ay)
,then the angle between vb1 and x-axis is φ=θ+π/2
so cos φ=cos(θ+π/2)=-sinθ=-ay, sinφ=sin(θ+π/2)=cosθ=ax
to calculate x-component of vb1 we need to calculate vb1*cos φ=vb1*(-ay)=-vb1*ay
,and (y-component of vb1) = vb1*sinφ=vb1*ax
 Logged
seenu
Newbie

Offline

Posts: 2

 « Embed this message Reply #110 on: May 01, 2009, 06:15:09 pm » posted from:Miamisburg,Ohio,United States

Hi again,

Now i understand how this is done.
in order to get the resultant new velocity for each ball , we add the new velocity vector to the perpendicular vector.
I am working on a demo applet to demonstrate this with many balls. I will post it once it is done.

Thank you
 Logged
jesims
Newbie

Offline

Posts: 1

 « Embed this message Reply #111 on: May 06, 2009, 10:06:16 pm »

cool post! very interesting!
-*-
 « Last Edit: May 06, 2009, 10:08:38 pm by jesims » Logged
batman009
Newbie

Offline

Posts: 1

 « Embed this message Reply #112 on: June 05, 2009, 04:04:39 pm » posted from:Batac,Ilocos Norte,Philippines

wonderful! thanks for the info..
 « Last Edit: June 05, 2009, 04:06:16 pm by batman009 » Logged
thegimel
Newbie

Offline

Posts: 2

 « Embed this message Reply #113 on: June 09, 2009, 04:33:42 am » posted from:,,Israel

excellent job breaking the physics/code down into easy bits and pieces!

i only have one question regarding the first part of the collision, where you take them back time dt so they exactly touch and don't overlap.

when you calculate the time you want to "playback" the system you use this formula: dt =(r1+r2-d)/(vp1-vp2).

then you take back the x,y coordinates by -vx/vy*dt

but what happens if (vp1-vp2) is negative, then the whole "dt" value is negative? after all, vp1 and vp2 are the values of the velocities, and it is possible that (vp1-vp2) is negative, no?

 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #114 on: June 09, 2009, 08:18:06 am » posted from:Taipei,T\'ai-pei,Taiwan

Good question.

dx=x2-x1, dy=y2-y1; $d=\sqrt{dx^2+dy^2}$;
vp1= vx1 *dx/d+vy1*dy/d;
vp2= vx2*dx/d+vy2*dy/d;
dt =(r1+r2-d)/(vp1-vp2);

The above equation using vector form (inner product).
$\hat{d}=\frac{\vec{x_2}-\vec{x_1}}{|\vec{x_2}-\vec{x_1}|}$, i.e. (dx/d,dy/d), is a unit vector.
$v_{p1}=\vec{v_1}\cdot \hat{d}$ and $v_{p2}=\vec{v_2}\cdot \hat{d}$ are results of inner product, both of them can be either positive or negative.

if (vp1-vp2) is negative, then the collision should not have happened.
For example: assume vy1=vy2=0 to make it simple to be understood.
dx coulbe be positive or negative:
1. if dx>0, i.e. x2>x1: it will require vx1>vx2 for collision to happened.
2. if dx<0, i.e. x2<x1: it will requires vx1<vx2 for collision to happened.
(vx1 and vx2 can be positive or negative for the above two cases)

That is the beauty of using vector to process the problem.
 Logged
thegimel
Newbie

Offline

Posts: 2

 « Embed this message Reply #115 on: June 09, 2009, 08:23:57 pm » posted from:,,Israel

Got it!

Thanks alot
 Logged
rahulpawar
Newbie

Offline

Posts: 4

 « Embed this message Reply #116 on: June 28, 2009, 04:25:27 am » posted from:Norway,South Carolina,United States

Hello prof.
i've problem. In this i want to simulate collision of 2 round pieces basically the same problem for which u have given the code. But in my case i "want" these to have reducing velocity, a deacceleration due to frictional force due to surface on which the pieces are sliding. Can u explain how this can be achived programatically ? A source code will be very helpful ?
 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #117 on: June 28, 2009, 08:26:42 am » posted from:Taipei,T\'ai-pei,Taiwan

Those two particles move with the same velocity when there is no collision.
For example: x+= vx*dt;

To change the velocity, it means that acceleration is not zero.
$\vec{a}=\tfrac{d\vec{v}}{dt}$
If acceleration is in the same direction as velocity, then the velocity will increase, otherwise it will decrease.
There are many way you can slow download the particle: you need to add a acceleration depend on what kind of situation need to be simulated.

For slidding friction: The friction force is $\mu N$, where N is the normal force (N=mg if it is a horizontal surface).
But you need to take care it is always in the opposition direction of the velocity.
And when it is stopped, the friction should disappear (You need to check this,too!).
I will leave it as an exercise for you.
Please try out to solve it by yourself. If you still can not solve it, write down what you did and what is the problem.
I will try to help after you have tried to help yourself. You will enjoy the fun when you solve it by yourself. :-)

 Logged
rahulpawar
Newbie

Offline

Posts: 4

 « Embed this message Reply #118 on: June 29, 2009, 06:22:52 pm » posted from:Falls Church,Virginia,United States

hello prof.
i went through the collision2D.java file there some variables are present within comment to implement "friction". Now the piece do slow down but they keep moving with small velocity after many collision. How do i go around ? The code is same as collision2D.java with comments removed. Also in my case i need the x,y cords & velocity of piece [ 1)initially, 2)at time of impact & 3)final position when velocity become 0] before actual display of pieces begin. That mean total algo is of 2 parts 1)calulation of cords & velocity and storing them in a array or struct(linkedlist) 2)displaying of pieces usinig that stored values. As u can see this is diff than what your applet does both at the same time. How to seperate them ?
 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #119 on: June 30, 2009, 12:26:14 pm » posted from:Taipei,T'ai-pei,Taiwan

The friction was not implemented properly in the code and it was not needed so it was commented out.
You need to determined what kind of friction you want to implemented.
Is it a constant friction force or a friction force which is proportional to velocity(e.g. particle moving in water)or event proportional to velocity square (small particle moving in air).

Change velocity as time move and check if velocity change sign to stop it (this is the point object fully stopped).

You can add code to disable display the view if you just want to stored all the data first without display it.
Then you need to add code to show the the drawing from the stored data. You need to allocate enough array to stored all the position (x,y) for each time steps.

Actually, you can calculate the time/position when/where two balls collide with each other and calculate how long the ball will move after collision. It can be done but you need to write down equations and solve it.
For example: if the velocity after collision is v. If the friction is F, then the longest distance traveled is d=mv2/2a

May I know what is the reason for your design? What is the purpose? May be there are better way to do it.
 Logged
 Pages: 1 2 3 [4] 5 6   Go Up
"Life is the beaty of art, heart, and humanity."...Wisdom