# NTNUJAVA Virtual Physics LaboratoryEnjoy the fun of physics with simulations! Backup site http://enjoy.phy.ntnu.edu.tw/ntnujava/

## JDK1.0.2 simulations (1996-2001) => Dynamics => Topic started by: Fu-Kwun Hwang on January 29, 2004, 04:08:42 pm

 Title: 2D Collision Post by: Fu-Kwun Hwang on January 29, 2004, 04:08:42 pm 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. Please do not ask me to send you the source code again!You are welcomed to check out another Collision 2D (http://www.phy.ntnu.edu.tw/ntnujava/index.php?topic=120.0) created with EJS. Please check out latest 2D collision created with EJS (http://www.phy.ntnu.edu.tw/ntnujava/index.php?topic=120.0)Let's consider collisions in two dimension:Press Start to begin the animation.Two circular objects will move with pre-defined velocity (yellow arrow).Click left mouse button to suspend the animation. Now, you can Click near the tip of the velocity vector and drag the mouse button left/right to change its value (the initial velocity of that object).Click near the circular boundary and drag the mouse button to change its radius.Right Click near the boundary of the circle to change it's size (also change it's mass, at the same time).Click near the center of the circle and drag the mouse to change its location.Click the mouse button again to resume the animation. When the two objects collide, the animation will be suspend.Press the mouse button ( Do not release it) to see the velocity vectors just after the collision.Press Reset button to reset parameters to default values.eta is the coefficient of restitution eat Vf/Vi Vf=relative velocity just after collision Vi=relative velocity just before collision  for elastic collision eta=1. for perfectly inelastic collision eta=0.You can select different frame of reference to view the relative motion of all the objects.lab is a laboratory inertial frame. m1, m2 and CM are frame of reference with respect to left circular object m1, right circular object m2 and center of mass for m1 and m2.View collision in 1 dimension.At the moment when they collide, the force between the two circle objects is along the line which connect the center of the two objects.Now we have 1-D collision problem:two object move in the direction along the line connect between their center, with velocitys along this directions. (Red vectors)The vector perpendicular to the above components (green vectors) will not changed after collision.(If there is no friction force between the two objects)Please check out Rigid Body Collisions (http://www.myphysicslab.com/collision.html) for 2D collision between rectangle shape objects. Title: How to convert 2D collision into 1D Post by: Fu-Kwun Hwang on October 28, 2004, 02:19:44 pm (http://www.phy.ntnu.edu.tw/demolab/phpBB/pics/2_2_collision2d.png)1. Find the time when two ball collide : D= R1+ R2 where D=Distance between center of two balls , and   R1/R2  is radius of each balls2.  Find the line connect center of  two balls. and calculate the component of the velocitry for each ball  alone the line connect those two balls.  For example : Velocity for each ball is Va and Vb (before collision)  Calculate Vap and Vbp. (and another normal component Van,Vbn)3. It is become a 1D collision problem: ball A with velocity Vap collide with ball B with velocity Vbp . You should be able to calculate velocity after collision for each ball.   for example:     Vap2=((m1-m2)/(m1+m2))vap+ (2m2/(m1+m2))Vbp and  Vbp2=(2 m1/(m1+m2))Vap+((m2-m1)/(m2+m1))Vbp  The tangential component is not changed Van2=Van, and Vbn2=Vbn4. Calculate the vector sum for velocity of each ball after collision  Va2=Vap2+Van2 and Vb2=Vb2p+Vbn2 (vector summation) Title: topic4 Post by: siput_tiung on March 12, 2005, 11:41:59 am hi,is there any difference between balls or humans when collision occur?i am trying to write a human model for collision cases... and still trying very2 hard to make it in realistic way. your applet seems like good for me and i'm impressed with it... perhaps it would be good to be applied to my project.. can u explain it in detail how's the calculation for it? dividing it into 3 condition,(1.before,2. during..,3.after.. )would be really2 great... thanks..ref: http://www.phy.ntnu.edu.tw/ntnujava/viewtopic.php?t=19Regards,Bazli Karimsiput_tiung@yahoo.com Title: topic4 Post by: Fu-Kwun Hwang on March 12, 2005, 02:20:41 pm The above calculation assume it is an elastic collision between two balls.i.e. No energy is loss during the collision.And the ball would not change shape.For collision betwen two human, we will change our body movment.Would you explain in more detail why you need to calculate collision between human?While two persons are walking or ...? Title: topic4 Post by: siput_tiung on March 14, 2005, 10:07:58 am let's see... here i'm trying to do collision avoidance among human...for example... human A is trying to go to point 1... and if there is another human blocking his way... then.. the human A must avoid it.. by changing to other direction and then, go to point 1..here... i can detect the collision if there is human blocking another human.. but, i have problem with changing direction... to make it realistic.. Title: topic4 Post by: Fu-Kwun Hwang on March 14, 2005, 02:33:38 pm Because you want to avoid collision among human. So there is no collision among human.You can check the velocity vector, if it is pointing to another person. Then someone is blocking his way.Provide the horizontal displayment, you can calculate the least change of the velocity.The person can change direction right at that point or change velocity gradually. Title: topic4 Post by: siput_tiung on March 16, 2005, 02:41:52 pm thanks.. i got the idea now.. Title: Java Code for collision in 2D Post by: Fu-Kwun Hwang on May 11, 2005, 07:03:51 am 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,y2dx=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 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 ball2double distance = Math.sqrt(dx*dx+dy*dy);// Unit vector in the direction of the collisiondouble ax=dx/distance, ay=dy/distance; // Projection of the velocities in these axesdouble 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=1double vaP1=va1 + (1+ed)*(va2-va1)/(1+mass1/mass2);double vaP2=va2 + (1+ed)*(va1-va2)/(1+mass2/mass1);// Undo the projectionsvx1=vaP1*ax-vb1*ay;  vy1=vaP1*ay+vb1*ax;// new vx,vy for ball 1 after collisionvx2=vaP2*ax-vb2*ay;  vy2=vaP2*ay+vb2*ax;// new vx,vy for ball 2 after collisionQuote(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 θ=aySo vap1*ax=vap1*cosθ give x-component of vap1, and vap1*ay give y-component of vap1Because vb1 and vb2 is in the direction perpendicular to the (ax,ay),then the angle between vb1 and x-axis is φ=θ+π/2so cos φ=cos(θ+π/2)=-sinθ=-ay, sinφ=sin(θ+π/2)=cosθ=axto calculate x-component of vb1 we need to calculate vb1*cos φ=vb1*(-ay)=-vb1*ay,and (y-component of vb1) = vb1*sinφ=vb1*axBecause 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. Title: topic4 Post by: rsnd on August 13, 2005, 10:33:14 am sorry for bothering :) Its probably a 3 year old thread!!!Just wondering...what does vx0 represent in your code?Thanks Rsnd Title: 2D and 3D Elastic Collision Solutions Post by: Thomas on September 17, 2005, 10:27:54 pm Anybody looking into the physics of 2D and 3D- elastic collisions may also be interested in my pages http://www.plasmaphysics.org.uk/collision2d.htm and http://www.plasmaphysics.org.uk/collision3d.htm which represent direct and general solutions of the problems. I have also written corresponding Fortran and C++ codes for this ( see http://www.plasmaphysics.org.uk/programs/coll2d_for.htm , http://www.plasmaphysics.org.uk/programs/coll2d_cpp.htm , http://www.plasmaphysics.org.uk/programs/coll3d_for.htm , http://www.plasmaphysics.org.uk/programs/coll3d_cpp.htm ) which are free to use for everybody.**************Note that there was a bug in the collision detection routine of the 2D-versions of my programs (this led in certain cases to collisions being detected when in fact there were none). I have corrected this now. I have also made minor changes to the code in order to improve speed. Furthermore I have added a simplified version to the 2D-routines that does not not contain the collision detection routine but just returns the new velocities assuming that the input coordinates are already those of the collision.Thomas, 11.Dec.05******************* Title: topic4 Post by: Fu-Kwun Hwang on September 21, 2005, 07:30:44 am Is there a vx0 posted in this forum messages! Please explain what do you mean? Title: DYNAMICS APPLET Post by: Janus20 on September 29, 2005, 09:56:41 am You have missed the spin component caused by the collision.It may have been there before collision occured.The spin neglect is an ENORMOUS ERROR. The information is dangerous due to its over simplification. Title: topic4 Post by: Fu-Kwun Hwang on October 18, 2005, 09:17:59 am Yes, the ball will also rotate if there are friction force between balls when collide.This is just an applet try to help student to understand basic physics (how to transform a 2D problem into two 1D problem). Title: 2-D collision for circular discs Post by: sujitkane on October 19, 2005, 06:01:46 pm Hello Professor HwangI have been following these pages since its publication in january 2004, just happened to register today. I wonder how different will it be if we consider that the two colliding bodies are two circular discs. You might have heard of a board game called carrom , its very popular in India. Do take a look at it. Now we have tried to emulate the example you have put up here and applied it to the emulation of carrom. There are  a few rough edges, but still the difference is not very clear. What changes will be necessary to make it work realistically?RegardsSujit Kane Title: topic4 Post by: Fu-Kwun Hwang on October 20, 2005, 08:06:24 am I do not know anything about carrom. Is there a URL for that?To add a rotation effect due to friction between two disks,  the mathematics become more comples. The friction between two disks is proportional to the normal force when two disks collide.F(friction) = mu * F(normal)The normal force is the rate of change of momentum (in the direction between two centers) when two disks collide.The friction force might change the tangential component of the velocity if the friction force is not large enough ( sliding occurs)The torque due to the friction will change the angular momentum for those two disks.In 2D collision: vx,vy and w (angular momentum) are changed due to collision for each ball.There are 6 variables need to be update for two balls, so you need to solve 6 equations. Title: topic4 Post by: pleasedontgocrazy on October 23, 2005, 10:42:16 pm what if the collision isnt perfectly inelastic/ elastic Title: topic4 Post by: Fu-Kwun Hwang on October 24, 2005, 07:45:39 am You just need to solve the problem differently for non- perfect elastic collision.Momentum is still conserved. But the energy is not conserved. Title: topic4 Post by: pleasedontgocrazy on October 25, 2005, 05:39:17 pm I keep trying to prove your equation by using the assumption that kinetic energy is not lost and momentum is not lost but I keep getting a different answer to yours. Could you give me some pointers about how to do solve it. SOLVED!Im doing this experiment for my A level coursework and I found that typically 90% of the mommentum is lost. Have I made a mistake? Title: topic4 Post by: pleasedontgocrazy on October 25, 2005, 06:56:26 pm Yes! Ive solved it (and got the correct answer)But this is for an elastic collision. For an partial inelastic collision which equation do I use for kinetic energy? Do you lose a certain amount of energy or is it a percentage of energy lost? Title: Sticky Balls Post by: SIBUK on November 28, 2005, 05:52:53 am Hi Professor Hwang,This article is fantastic and has helped me a lot, but I am wondering if you might be able to help me out with a problem I have. I have made a program where I have multiple balls on the screen, each moving at a random velocity and in a random direction. The problem I have is that when 2 balls collide, they will often stick to each other (especially when ed is < 1) and spin around orbiting each other. Each of the balls has a radius of 15, and so my collision detection is very simple, when the distance between two balls is <= 30 then there has been a collision. So, the problem is that when the distance is less than 30, (say 25), then they are overlaping by 5, when I next update the positions of the balls, if they havnt moved more than a distance of 5 away from each other since the last update, then they are still overlapping and the collision is still true. So, what I need to do is before the next update, I need to move the balls appart from each other a distance of 5 in the new direction after the impact. But I cant seem to figure out the maths to do it.Also, I have implemented a bit of code to help handle when 3 or more balls collide at the same time, but it doesnt quite seem to work right. Do you have any tips for this? Title: topic4 Post by: Fu-Kwun Hwang on April 15, 2006, 02:11:56 pm The real collision should have occured before you detected that the distance between two center of the balls d is less than the sum of those two balls r1+r2.The correct way is to find the time when the two ball real collide with each other.Suppose the center of those two ball are x1,y2 and x2,y2dx=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+vy2*dy/d;Collision should have happened dt before you have detected r1+r2}Code:static void ball_collision(struct ball *ball_a, struct ball *ball_b){   float dx = ball_b->x - ball_a->x;   float dy = ball_b->y - ball_a->y;   float d = sqrt(dx*dx+dy*dy);   if(d<=(float)bmap_ball.height) // r1+r2 = bmap_ball.height   {      // first we calculate the velocity in the direction of (dx,dy)      float vp_a = (ball_a->vx*dx + ball_a->vy*dy)/d;      float vp_b = (ball_b->vx*dx + ball_b->vy*dy)/d;      // collision should have happened dt before      float dt =((float)bmap_ball.height-d)/(vp_a-vp_b);      // we should move those ball backward      ball_a->x -= ball_a->vx*dt;      ball_a->y -= ball_a->vy*dt;      ball_b->x -= ball_b->vx*dt;      ball_b->y -= ball_b->vy*dt;      dx = ball_b->x - ball_a->x;      dy = ball_b->y - ball_a->y;      d = sqrt(dx*dx+dy*dy);      // calculate the components of velocity      float ap = dx/d;      float an = dy/d;      vp_a = ball_a->vx*ap + ball_a->vy*an;      float vn_a = ball_a->vx*an - ball_a->vy*ap;      vp_b = ball_b->vx*ap + ball_b->vy*an;      float vn_b = ball_b->vx*an - ball_b->vy*ap;            // calculate new velocity for those balls after collision      ball_a->vx = vp_b*ap + vn_a*an;      ball_a->vy = vp_b*an - vn_a*ap;      ball_b->vx = vp_a*ap + vn_b*an;      ball_b->vy = vp_a*an - vn_b*ap;      // now we need to move time dt forward      ball_a->x += ball_a->vx*dt;      ball_a->y += ball_a->vy*dt;      ball_b->x += ball_b->vx*dt;      ball_b->y += ball_b->vy*dt;   }}and im stuck  ???regards,Bartekoh, and mass1 = mass2 and eta =1 Title: Re: 2D Collision Post by: Fu-Kwun Hwang on February 22, 2007, 04:48:24 pm This is the java code I use in my simulation:Code:        r12=Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); cs=(x2-x1)/r12; sc=(y2-y1)/r12; vp1=vx1*cs+vy1*sc; vp2=vx2*cs+vy2*sc; // back to collision time ddt=(dmin-r12)/(vp1-vp2); if(ddt>dt)ddt=0.; x1-=vx1*ddt; y1-=vy1*ddt; x2-=vx2*ddt; y2-=vy2*ddt; r12=Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); //calculate component of velocity cs=(x2-x1)/r12; sc=(y2-y1)/r12; vp1=vx1*cs+vy1*sc; vp2=vx2*cs+vy2*sc; //  normal components do not change vn1=vx1*sc-vy1*cs; vn2=vx2*sc-vy2*cs;       //calculate component of velocity in original X,Y coordinate px1=vp1*cs; py1=vp1*sc; px2=vp2*cs; py2=vp2*sc; nx1=vn1*sc; ny1=-vn1*cs; nx2=vn2*sc; ny2=-vn2*cs; } Title: Re: 2D Collision Post by: solashok on February 28, 2007, 09:22:43 am Respected Sir,  when two atoms collide using Conservation of Momentum and Energy we get expression for E2 = 4M1M2 cos square phi E0/(M1 + M2)square. Can U suggest me how this has come. Title: Re: 2D Collision Post by: Fu-Kwun Hwang on February 28, 2007, 10:15:32 am What is the situation you want to discuss about? There is no way to discuss if question is not well defined!What are the meaning for E0,E2 and what is the formula you want to show?And how did you get that formula? ???  Title: Re: 2D Collision Post by: mrsdost on April 18, 2007, 11:13:41 pm Hello Professor,I am currently working on the following question and was wondering if you could offer any help. I'm just not sure how to factor in the 30 degrees. this is of course a completely elastic collision. any help would be great.Thanks,mrsdostTwo pool balls are rolling along a pool table. The red pool ball has a velocity of 10 cm/s west and the blue ball a velocity of 10 cm/s north 30° east. What are the velocities of the balls after the collision? Title: Re: 2D Collision Post by: Fu-Kwun Hwang on April 19, 2007, 01:01:41 am You can find out the answer easily.Just use mouse to drag the velocity vector for each ball in the simulation (conditions match with your problem) and find out the answer by yourself! Title: Re: 2D Collision Post by: mrsdost on April 19, 2007, 09:55:36 pm Thank you Professor,but i need to learn how to do the calculations myself.So if you could help me with some formulas that include the vectors of the balls that would be great.Thank you,Mrsdost Title: Re: 2D Collision Post by: Fu-Kwun Hwang on April 19, 2007, 10:09:51 pm Please look at all the forum messages in this topic carefully,  all the steps (in detail) have been posted (http://www.phy.ntnu.edu.tw/ntnujava/index.php?topic=4.msg15#msg15).I guess you did not read this forum messages carefully.If you did read it and still did not understand it. Please at least indicate where you did not get it. ::) Title: Re: 2D Collision Post by: arthurprs on July 22, 2007, 01:41:57 am Hi professor, sorry to bother you, but im having some dificult here to make your code work  ???This is my code in OPascalnot much dif from javaCode:        dx := ball[i].cx - ball[n].cx;        dy := ball[i].cy - ball[n].cy;        dist := Sqrt(Power(dx, 2) + Power(dy, 2));        if dist <= (ball[i].raio + ball[n].raio) then        begin          ax := dx / dist;          ay := dy / dist;          vp_n := (ball[n].vx * ax) + (ball[n].vy * ay);          vp_i := (ball[i].vx * dx) + (ball[i].vy * ay);          dt := ((ball[i].raio + ball[n].raio) - dist) / (vp_n + vp_i);          ball[n].x := ball[n].x - (ball[n].vx * dt);          ball[n].y := ball[n].y - (ball[n].vy * dt);          ball[i].x := ball[i].x - (ball[i].vx * dt);          ball[i].y := ball[i].y - (ball[i].vy * dt);You can see something wrong ?*sorry my bad english, im from brazilEDIT: If u can send me the source code to my email it will be helpfull too Title: Re: 2D Collision Post by: Fu-Kwun Hwang on July 23, 2007, 03:35:51 pm You can find out the code related to what you need from previous messages.You are not following the same steps I did.Please read it more carefully. Title: Re: 2D Collision Post by: arthurprs on July 24, 2007, 01:29:19 am Quote from: Fu-Kwun Hwang on July 23, 2007, 03:35:51 pmYou can find out the code related what you need from previous messages.You are not following the same steps I did.Please read it more carefully. ok. Title: Re: 2D Collision Post by: Fu-Kwun Hwang on July 24, 2007, 03:04:13 pm Please following the code I did in my previous messages. Post the code again if you still have the problem. Title: Re: 2D Collision Post by: arthurprs on July 26, 2007, 09:44:45 am Quote from: Fu-Kwun Hwang on July 24, 2007, 03:04:13 pmPlease following the code I did in my previous messages. Post the code again if you still have the problem.Hey professor i did it, but somethimes the balls don't colide right  ???anything wrong with my code ?Code:  for n := 0 to Length(ball)-1 do  begin // n = currentball  // wall hit    //x    if (ball[n].x <= 0)      or (ball[n].x2 >= Form1.ClientWidth) then    begin      ball[n].vx := -ball[n].vx {* 0.9};    end;    //y    if (ball[n].y <= 0)      or (ball[n].y2 >= Form1.ClientHeight) then    begin      ball[n].vy := -ball[n].vy {* 0.9};    end;  // other balls hit    for i := 0 to Length(ball)-1 do // i = other ball      if ((i <> n) and (not (ball[i].colided)) and (not (ball[n].colided))) then      begin        dx := ball[i].cx - ball[n].cx;        dy := ball[i].cy - ball[n].cy;        dist := Sqrt(Power(dx, 2) + Power(dy, 2));        if dist <= (ball[i].raio + ball[n].raio) then        begin          //          ax := dx / dist;          ay := dy / dist;          vp_n := (ball[n].vx * ax) + (ball[n].vy * ay);          vp_i := (ball[i].vx * dx) + (ball[i].vy * ay);          dt := ((ball[i].raio + ball[n].raio) - dist) / (vp_n + vp_i);          ball[n].x := ball[n].x - (ball[n].vx * dt);          ball[n].y := ball[n].y - (ball[n].vy * dt);          ball[i].x := ball[i].x - (ball[i].vx * dt);          ball[i].y := ball[i].y - (ball[i].vy * dt);          ball[n].Refresh;          ball[i].Refresh;          //          dx := ball[i].cx - ball[n].cx;          dy := ball[i].cy - ball[n].cy;          dist := Sqrt(Power(dx, 2) + Power(dy, 2));          ax := dx / dist;          ay := dy / dist;          vp_n := ball[n].vx * ax + ball[n].vy * ay;          vp_i := ball[i].vx * ax + ball[i].vy * ay;          vn_n := ball[n].vy * ay - ball[n].vy * ax;          vn_i := ball[i].vy * ay - ball[i].vy * ax;          vn:= vp_n + (1+ed)*(vp_i - vp_n)/(1+ball[n].mass/ball[i].mass);          vi:= vp_i + (1+ed)*(vp_n - vp_i)/(1+ball[i].mass/ball[n].mass);          ball[n].vx:= vn*ax-vn_n*ay;          ball[n].vy:= vn*ay+vn_n*ax;          ball[i].vx:= vi*ax-vn_i*ay;          ball[i].vy:= vi*ay+vn_i*ax;          ball[n].Refresh;          ball[i].Refresh;          ball[n].colided:=True;          ball[i].colided:=True;        end;      end;  end;  for n := 0 to Length(ball) - 1 do  begin    ball[n].Move;  end;end;2 ballsboth mass = 1 and ed = 1 Title: Re: 2D Collision Post by: Fu-Kwun Hwang on July 26, 2007, 10:43:11 am You did not read my post carefully.You did not do the following steps:First calculate the component of velocity in the direction of (dx,dy)vp1= vx1 *dx/d+vy1*dy/d;vp2= vx2*dx+vy2*dy/d;Collision should have happened dt before you have detected r1+r2 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;Next : do the collision parts. as the normal case.And move the time forward: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.Please read the following post carefully and follow all the steps. http://www.phy.ntnu.edu.tw/ntnujava/index.php?topic=4.msg15#msg15 Title: Re: 2D Collision Post by: estruiz on July 27, 2007, 05:30:46 am Hi ProfessorMy name is Esteban and I need some help.  I do not know much about physics, but this past year i've been trying to solve a head on collision between a 98 Dodge ram 1500 quad cab 4x4 (5251 lbs.) and a Pontiac Grand AM 4 door sedan (3650 lbs.).  The pontiac is heading south and the dodge is heading north.  The speed of the car is unknown and the speed of the truck is 43 mph +-.  No breaks where applied to neither vehicles.  The friction of the road is 0.565.  The car heading south crossed over the centerline at an angle of 14 degrees and when realized they where in the oncoming lane they tried to steer to their right which sent their car out of control and made their tail end slide sideways.  the car is still heading in the same 14 degrees, but now going sideway almost at 90 degrees to the 14 degree direction.  Both truck and car impact on the left front bumpers (driver side).  Both left front tires from each vehicle are locked.  The truck is sent backwards about 19 feet and its final resting position is facing east.  The car is sent east of the impact about 18 feet and about 8 feet north of the impact with the car facing south.  the dimensions of the road are 28 feet from edge of pavement to edge of pavement so 14 feet from centerline to EOP. The slope of the road heading south is S=1.45% south and the entire road slopes to the east at 2.75%.  What I need to know if this is possible and if it is, at what speed does the car need to be traveling to be able to push back the truck?  Please email me if you need any more information at estruiz@msn.com Title: Re: 2D Collision Post by: Fu-Kwun Hwang on July 27, 2007, 09:20:00 am "the car is still heading in the same 14 degrees, but now going sideway almost at 90 degrees to the 14 degree direction."I do not quite understand the above situation? And is it happened before the collision?"The slope of the road heading south is S=1.45% south and the entire road slopes to the east at 2.75%.  "I did not understand the above statement,either!The car is sent east of the impact about 18 feet, But from center to edge of pavement is 14 feet, so the car is out of the pavement?Without consider the above parameters. From the impact distance in the north-south direction. I try to estimate the speed right after the impact for both car:Assume the stopping distance are all due to friction of the road (which might not be true if car was flying after the impact) The following are very rough estimation and base on  the above assumption:acceleration for both car assume to be the same: a=-0.565*9.8=5.537 m/s^2v=sqrt(2*a*s)=sqrt(2*9.8*0.565*s) 19 feet=5.79 m so the speed is about 8 m/s  So it took 1.4 s to fully stopped after the collision.8 feet=2.43m so the speed is about 5.2m/s  So it took 0.9s to fully stopped after the collision.Initial speed for the truck is 43mph=69km/hr=19.2m/sAssume conservation of momentum during collision3650*(v+5.2)=5251*(19.2+8) so v=33.9m/s = 122 km/hr= 75.9 mph (estimated speed for the car)Because the mass for the car is smaller than the truck and the bounce off distance for the car is less than the truck, so the speed of the car is larger than the truck. However, the above estimate are based on very simple model. I believe local police agent should have gather more data to provide a better estimation. Title: Re: 2D Collision Post by: arthurprs on July 28, 2007, 12:50:27 pm Quote from: Fu-Kwun Hwang on July 26, 2007, 10:43:11 amYou did not read my post carefully.You did not do the following steps:First calculate the component of velocity in the direction of (dx,dy)vp1= vx1 *dx/d+vy1*dy/d;vp2= vx2*dx+vy2*dy/d;Collision should have happened dt before you have detected r1+r2 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;Next : do the collision parts. as the normal case.And move the time forward: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.Please read the following post carefully and follow all the steps. http://www.phy.ntnu.edu.tw/ntnujava/index.php?topic=4.msg15#msg15yes i did it in lines 30 and 31 =/ Title: Re: 2D Collision Post by: Fu-Kwun Hwang on July 28, 2007, 08:39:48 pm You are checking collision between n particles with loop likefor(int i=0;i for(j=0;j }}In the above case, collision between particles might be processed twice.You can change the loop tofor(int i=0;i for(j=0;j   if(i!=j){// particle can not collide with itself   } }And I did not fully understand what do you mean by"somethimes the balls don't colide right  Huh"!You only tell me you think there is something wrong, But I did not know what is wrong!} Title: Re: 2D Collision Post by: arthurprs on July 29, 2007, 02:49:09 pm Quote from: Fu-Kwun Hwang on July 28, 2007, 08:39:48 pmYou are checking collision between n particles with loop likefor(int i=0;i>        dt:Number=(r1+r2-d)/(vp1+vp2);                                   // move back           cararray[i1].x-=cararray[i1].velx*dt;           cararray[i1].y-=cararray[i1].vely*dt;           cararray[i2].x-=cararray[i2].velx*dt;           cararray[i2].y-=cararray[i2].vely*dt;                             dx=cararray[i1].x-cararray[i2].x;           dy=cararray[i1].y-cararray[i2].y;            d=Math.sqrt(dx*dx+dy*dy);                                            // unit vector in the direction of the collision                      var ax:Number=dx/d , ay:Number=dy/d;                                               // projection of the velocities           var va1:Number=( cararray[i1].velx*ax+cararray[i1].vely*ay),                vb1:Number=(-cararray[i1].velx*ay+cararray[i1].vely*ax),      va2:Number=( cararray[i2].velx*ax+cararray[i2].vely*ay),      vb2:Number=(-cararray[i2].velx*ay+cararray[i2].vely*ax);                                            // new velocities after collisions             var vap1:Number=va1+(1+cr)*(va2-va1)/(1+cararray[i1].mass/cararray[i2].mass),           vap2:Number=va2+(1+cr)*(va1-va2)/(1+cararray[i2].mass/cararray[i1].mass);                                      // undo the projections (new velocities after collision)           cararray[i1].velx=vap1*ax-vb1*ay;            cararray[i1].vely=vap1*ay+vb1*ax;           cararray[i2].velx=vap2*ax-vb2*ay;           cararray[i2].vely=vap2*ay+vb2*ax;                             // move forward           cararray[i1].x+=cararray[i1].velx*dt;           cararray[i1].y+=cararray[i1].vely*dt;           cararray[i2].x+=cararray[i2].velx*dt;           cararray[i2].y+=cararray[i2].vely*dt;       }   }} Title: Re: 2D Collision Post by: Fu-Kwun Hwang on October 26, 2007, 05:10:04 pm I am not familiar with the syntax in your code. var i2:uint=i1+1;// Does it mean i2=i1+1;??? I wrote some action code in flash before, but it was almost the same as java-script.But the problem only occurred for some occasional case, so most part of the code should be all right.When the ball was pushed away, is it with a much larger velocity? If this is the case, you can add some code to print out related information when such case happened, in order to find out what went wrong. Title: Re: 2D Collision Post by: Manav on October 31, 2007, 10:09:20 am Hello Professor Hwang,     You might have guessed my name, it's Manav. In my class we have been creating a class to emulate the physics aspect for a bouncing ball in C++ and using the glut class from OpenGL to show the ball. So far in our class we have many balls that can bounce and slow down due to gravity. I wanted to do more since I am a little bored and so I've been trying to mold your 2D collision of balls for my 3D collision for my balls. Since I registered with the forum just now (which by the way was very helpful for me to get started) I am having troubles. I am stuck at trying to do the part where you calculated the projection velocities, since I have to deal with 3 dimensional vectors. Help would be greatly appreciated. The following is the code for my collision procedure in my C++ class:Code:void BallObject::Collision(BallObject ball){ double r1 = diameter / 2; //first ball's radius double r2 = ball.diameter / 2; //second ball' radius double dx = ball.position[0] - position[0]; double dy = ball.position[1] - position[1]; double dz = ball.position[2] - position[2]; double d = sqrt((dx*dx) + (dy*dy) + (dz*dz)); double dt; double vp1 = (velocity[0]*(dx/d)) + (velocity[1]*(dy/d)) + (velocity[2]*(dz/d)); double vp2 = (ball.velocity[0]*(dx/d)) + (ball.velocity[1]*(dy/d)) + (ball.velocity[2]*(dz/d)); if(r1 + r2 < d){ dt =(r1+r2-d)/(vp1+vp2); position[0] -= velocity[0]*dt; position[1] -= velocity[1]*dt; position[2] -= velocity[2]*dt; ball.position[0] -= ball.velocity[0]*dt; ball.position[1] -= ball.velocity[1]*dt; ball.position[2] -= ball.velocity[2]*dt;         } Title: Re: 2D Collision Post by: Fu-Kwun Hwang on October 31, 2007, 07:38:53 pm For the code in the previous message, you just move those two ball back to the point where the collision occurred.(The above solution is an approximation, it is not an exact solution. But it should work fine when the velocity*dt << size of the ball).I do not know what can I help. Title: Re: 2D Collision Post by: Manav on November 01, 2007, 01:12:19 am Hi, its me again and the problem I'm having with is converting the following part for a 3 dimensional ball:// Unit vector in the direction of the collisiondouble ax=dx/distance, ay=dy/distance;// Projection of the velocities in these axesdouble 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=1double vaP1=va1 + (1+ed)*(va2-va1)/(1+mass1/mass2);double vaP2=va2 + (1+ed)*(va1-va2)/(1+mass2/mass1);// Undo the projectionsvx1=vaP1*ax-vb1*ay;  vy1=vaP1*ay+vb1*ax;// new vx,vy for ball 1 after collisionvx2=vaP2*ax-vb2*ay;  vy2=vaP2*ay+vb2*ax;// new vx,vy for ball 2 after collisionIn the above code you only deal with x, and y direction, but i want to try to also include a z direction as well and I do not know how to do the calculation with x, y, and z direction since the ball I'm working on has an x, y, and z position vector.   Title: Re: 2D Collision Post by: Fu-Kwun Hwang on November 01, 2007, 04:32:00 pm I am going to assume you fully understand vector and the inner product between two vectors.If there are vector A and another vector B. (use bold face to represent vector)Let the unit vector of A is a=A/|A|, and b=B/|B|, where |A|, |B| are the length of A,BYou can calculate the projection of vector A in the direction of B with A• B/|B| =A• b : where • mean inner productIn 2D, ax=dx/distance, ay=dy/distance so (ax,ay) is the unit vector in the direction between center of those two balls. So the projection of velocity(vx,vy)  in the direction of (ax,ay) is  vx*ax+vy*ay For the code: ouble va1=(vx1*ax+vy1*ay), vb1=(-vx1*ay+vy1*ax);double va2=(vx2*ax+vy2*ay), vb2=(-vx2*ay+vy2*ax);Now, you know why va1,va2 can be calculated with the above formula.vb1,vb2 are the normal components -- perpendicular to the (vx,vy)So the unit vector is (-ay, ax)  -- (ax,ay)•(-ay,ax)=0 so those two vectors are perpendicular to each other.For the 3D case, you just need to add another component (z) and calculate it in the same way.I hope you can understand it. If not, let me know and I will try to explain it in more detail.However,  I want you to understand it, so you will be able to solve similar problem next time. That is why I do not want to give you the exact solution. And you will be more confident when you can solve it by yourself.  You will enjoy the fun of learning this way,too!  ;) Title: Re: 2D Collision Post by: Manav on November 02, 2007, 01:03:21 am Thanks a lot professor Hwang,    I finally incorporated the z axis into the calculation, but i have one final question. Couldyou tell the reason for having dt and what it is doing to the balls in the program. And once againTHANK-YOU very much. Title: Re: 2D Collision Post by: Fu-Kwun Hwang on November 02, 2007, 09:09:03 am It was explained in the previous message.In the simulation (or computer programming), the time step is a finite step.The collision should have happened (It should occurred when R1+R2=d), before the program detect those two ball collided ( R1+R2 > d, where d is the distance between two balls, and R1,R2 are the radius).So we calculate the relative velocity in the direction between center of two balld, and estimate the time collision should have happened (dt). So we move the ball back to the moment when the collision should have occurred (let the time move backward by dt, or let particle move backward by v*dt !). Do the calculation for collision, and move time step dt forward again . Title: Re: 2D Collision Post by: Manav on November 02, 2007, 10:35:35 am wow :o, so dt meant the time for the ball to have collided, I'm sorry i was confusing dt withsome sort of distance :-[. Professor Hwang you have been an amazing teacher.Thank-You   ;DAlso I was wondering should I post how i did the calculation for finding the final velocities of the two ball inThree-dimension? Title: Re: 2D Collision Post by: Fu-Kwun Hwang on November 02, 2007, 09:46:30 pm You can decide it by yourself. It's all depend on what the purpose for the posting.You can post it so that the other user can copy it for similar work, or you want other to do the calculation by herself/himself. Title: Re: 2D Collision Post by: Manav on November 02, 2007, 10:21:29 pm I guess I'll let people do the calculations by themselves since it turned out to be reallyeasy, but I'll give the other people a hint: When you calculate for a 2-d collisionyou calculate for the normal vector and a tangent vector like how Professor Hwanghad done "Va1 and Va2 were calculated using the normal vector and Vb1 and Vb2were calculated using". When you are calculating for a 3-d collision you have tofind i second tangent vector and just adjust the equations professor has to incluethe z direction in (x, y, z). If you require more detail for an elastic 2-d collisionequations use the following site: http://www.geocities.com/vobarian/2dcollisions/2dcollisions.pdf (http://www.geocities.com/vobarian/2dcollisions/2dcollisions.pdf)Please correct me if I am wrong and than-you.  Title: Re: 2D Collision Post by: Manav on November 02, 2007, 10:24:16 pm I am really sorry people the following sentence from above should look like this:"Va1 and Va2 were calculated using the normal vector and Vb1 and Vb2were calculated using the tangent vector".Once again I am sorry this is my first forum visit ever. Title: Re: 2D Collision Post by: sabeeh on November 16, 2007, 04:49:44 am Thank you very much for this effort in order to benefit from the computer and the Internet in the area of knowledge transfer Title: Re: 2D Collision Post by: vanmobi on December 19, 2007, 03:52:44 am Hello professor,I am trying to implement the algorithm you described with a small difference: my speed is constantly slowly decreasing so my balls will come to a stop after a while. In your explanation, the speeds are constant.  Can you please let me know what needs to be changed to implement my deceleration? Detecting the time the collision will take place is tricky. I guess I need to introduce the notion of acceleration (negative in my case). Thank you! Title: Re: 2D Collision Post by: colos on December 19, 2007, 07:20:11 am The easier way is to introduce a drag force which is proportional to velocity.F= -b*V , b and initial velocity will determine how far the ball stop. Title: Re: 2D Collision Post by: vanmobi on December 19, 2007, 08:56:58 pm Thank you. Yes, this seems like the right way of doing it.But I have no idea how to apply this to the existing formulas?1. What is the impact on the calculation of the component of velocity in the direction of (dx,dy)vp1= vx1 *dx/d+vy1*dy/d;vp2= vx2*dx+vy2*dy/d;2. How do I compute the collision time?dt =(r1+r2-d)/(vp1+vp2);// the collision should have occurred at t-dtThank you for your help!Vanessa Title: Re: 2D Collision Post by: Fu-Kwun Hwang on December 19, 2007, 10:51:52 pm Sorry! I mis-understood your questionQuoteI am trying to implement the algorithm you described with a small difference: my speed is constantly slowly decreasing so my balls will come to a stop after a while. In your explanation, the speeds are constant. I did not look at your previous message carefully. I thought in my case, the total energy of those balls should be constant (energy is conserver) and you want the ball to slow down.It is the opposite.  You much have done something wrong so those balls are slowing down. You need to write down how you did it. Otherwise, there is no way I can find out why it is so.For computer code, the time is increases a finite amount. So the ball will change position a finite distance for each time step. At the time you found those two ball collide (d(At the time two ball collide, d is equal to r1+r2).So we need to move the time backward a little so we can find out when those two ball really collide.I use an approximation to find the time dt. (r1+r2-d2) is the differences, and vp1,vp2 are velocity almost along the line between center of two ball. So dt=(r1+r2-d2)/(vp1+vp2) will move the ball back to the time those two ball just collide.But your problem has nothing to do with the above miner correction.  You must have use the wrong formula for the collision so the speed is decreasing. Title: Re: 2D Collision Post by: vanmobi on December 20, 2007, 01:05:28 am Actually, they currently are not slowing down, but I want them to. Just like in a billiard game, after a while, the balls will stop rolling. That's the behavior I am try to implement.So if I introduce a friction of some sort, what is the implication on the formulas?Thank you,Vanessa Title: Re: 2D Collision Post by: Fu-Kwun Hwang on December 21, 2007, 03:20:16 pm O.K. So yo do want to add a friction effect. A simple model: F= m*g*u,  which is a constant for each ball.So the distance for a ball to stop will proportional to it's kinetic energy K=(1/2)m*v2This could be a good model for your case. Title: Re: 2D Collision Post by: pepsicoder on January 26, 2008, 01:40:38 pm vp1= vx1*dx/d+vy1*dy/d;vp2= vx2*dx+vy2*dy/d; // << Is this line a wrong.Should this code be :-vp1= vx1*dx/d+vy1*dy/d;vp2= vx2*dx/d+vy2*dy/d; Title: Re: 2D Collision Post by: Fu-Kwun Hwang on January 28, 2008, 11:55:35 pm Yes. It should bevp1= vx1*dx/d+vy1*dy/d;vp2= vx2*dx/d+vy2*dy/d;orvp1= (vx1*dx/d+vy1*dy)/d;vp2= (vx2*dx+vy2*dy)/d; It is an inner product between two vector (vx,vy) and (dx/d,dy/d) Title: Re: 2D Collision Post by: acw on April 20, 2008, 03:29:38 am thanks for a really nice site, helped me a lot=)got a few questions:1. how can i get a applet to work for other regular geometric figures like an rectangle. i cant go with the distance/pythagoras there since the corners will then be ignored. also could you tell me how this is done for iregular figures in short words. (just wanna know basic theori how this is done since this is way over my level).2. i was able to implement parts of your code into my own applet to make it more realistic, however sometimes the objects get stuck in each other or in the borders.althougth you were very clear in your instructions i wasnt able to fully understand how to keep them from doing that. (something with moving them one step away from each other in the if statement i think?)Code:for(int i = 0;i < 3;i++){ for(int j = i+1;j<4;j++){ if(Math.sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]))<=30){ int dx=x[j]-x[i]; int dy=y[j]-y[i]; double d = Math.sqrt(dx*dx+dy*dy); double ax=dx/d, ay=dy/d; double va1=(vx[i]*ax+vy[i]*ay), vb1=(-vx[i]*ay+vy[i]*ax); double va2=(vx[j]*ax+vy[j]*ay), vb2=(-vx[j]*ay+vy[j]*ax); vx[i]=va2*ax-vb1*ay;  vy[i]=va2*ay+vb1*ax; vx[j]=va1*ax-vb2*ay;  vy[j]=va1*ay+vb2*ax; } }}also would be nice if you could give the physic formula for these lines. i ingnored mass and some other factors that didnt matter in my program since same size on all objects, but would like them in the formula aswell.   Code:double ax=dx/d, ay=dy/d; double va1=(vx[i]*ax+vy[i]*ay), vb1=(-vx[i]*ay+vy[i]*ax); double va2=(vx[j]*ax+vy[j]*ay), vb2=(-vx[j]*ay+vy[j]*ax);Thanks Title: Re: 2D Collision Post by: Fu-Kwun Hwang on April 20, 2008, 08:48:39 am 1. The boundary of any shape is just connected lines (polygon). You need to check if any two lines from different object connected(in contact) with each other.You can check out ParticlesAndWalls (http://www.phy.ntnu.edu.tw/ntnujava/index.php?topic=164.0) applet: you can draw any shape and particle will be bounded in the region you have created. (Click Usage link under applet to see flash demo). You can check out our EJS code and find out how it was implemented.2. You should write down formulas for your code. Your code should be based on your equations. Title: Re: 2D Collision Post by: amol on May 07, 2008, 12:42:17 pm Hi professor,grt site.....i really like ur work and the way u r carrying it..thanx and good luck..also looking forward  for the  post for gaming people Title: Re: 2D Collision Post by: amol on May 07, 2008, 11:29:46 pm Hello sir,i have tried to make the collision of two balls.I have followed the steps u have written in some previous post.in my case i have kept one ball at rest, and other moving.But after collision the behaviour of both the ball is weired.here is my code   int dx = ball[1].x - ball[0].x;   int dy = ball[1].y - ball[0].y;      double dist = MathHelper::sqrt(dx*dx + dy*dy);   //Unit vector in the direction of collision   double ax = dx /dist;   double ay = dy/dist;if(dist < 10) // (actually r1+r2 = 10){   // Projection of the velocities in these axes   double va1=(ball[0].vx*ax+ball[0].vy*ay), vb1=(-ball[0].vy*ay+ball[0].vy*ax);    double va2=(ball[1].vx*ax+ball[1].vy*ay), vb2=(-ball[1].vx*ay+ball[1].vy*ax);   // New velocities in these axes (after collision): ed<=1,  for elastic collision ed=1double vaP1=va1 + (1+1)*(va2-va1)/(1+1);double vaP2=va2 + (1+1)*(va1-va2)/(1+1);// Undo the projectionsball[0].vx=(int)(vaP1*ax-vb1*ay);  ball[0].vy=(int)(vaP1*ay+vb1*ax);// new vx,vy for ball 1 after collisionball[1].vx=(int)(vaP2*ax-vb2*ay);  ball[1].vy=(int)(vaP2*ay+vb2*ax);// new vx,vy for ball 2 after collision}Please comment on this. thanx. Title: Re: 2D Collision Post by: Fu-Kwun Hwang on May 08, 2008, 12:04:09 am I would suggest you check the momentum and energy just before and right after the collision.If it is the same, then there is nothing wrong with the collision.After the collision the behavior of both balls are wired, may be it is not due to collision , it is due to some other code. And what do you mean by wired? There is no way to help without detail information. Title: Re: 2D Collision Post by: amol on May 08, 2008, 02:38:01 am Hello sir,The motion of two ball is weired means they stick each other and after that there is no movement for both the ball.Sometimes after hitting one ball stops  and other keep moving.when they stop moving at that time velocities i got for ball in x and y directions are 0 and ball stops.// Projection of the velocities in these axesdouble va1=(ball[0].vx*ax+ball[0].vy*ay), vb1=(-ball[0].vy*ay+ball[0].vy*ax); double va2=(ball[1].vx*ax+ball[1].vy*ay), vb2=(-ball[1].vx*ay+ball[1].vy*ax);// New velocities in these axes (after collision): ed<=1,  for elastic collision ed=1double vaP1=va1 + (1+1)*(va2-va1)/(1+1);double vaP2=va2 + (1+1)*(va1-va2)/(1+1);// Undo the projectionsball[0].vx=(int)(vaP1*ax-vb1*ay); ball[0].vy=(int)(vaP1*ay+vb1*ax);// new vx,vy for ball 1 after collisionball[1].vx=(int)(vaP2*ax-vb2*ay);  ball[1].vy=(int)(vaP2*ay+vb2*ax);// new vx,vy for ball 2 after collisionHere i got the veocities 0 and ball stops.But rest of the time collision is perfect.Thank you. Title: Re: 2D Collision Post by: Fu-Kwun Hwang on May 08, 2008, 11:17:30 pm (From the information you have provided in the above message). I think your problem is due to you did not correct the small time different between collision real happened and the time your program detect the collision.The condition used to detect the collision in your code is dist< r1+r2However, collision occurred when dist==r1+r2. So there is a small error. If the time step is small enough, the error can be ignored.The problem is worse for programming in flash actionscript(because the time step is too large, 12fps?)Please check out another message at this topic: http://www.phy.ntnu.edu.tw/ntnujava/index.php?topic=4.msg15#msg15and you will find out how to correct it (another approximation!). Title: Re: 2D Collision Post by: ObsessedOne on May 18, 2008, 01:59:02 am Hello Professor HwangI have been working on this simulation for quite a while now. I feel that I am very, very close. I still have the time error where they clutch together but they aren't completely stuck. Most of the time they bounce, but other times they do not. Do you see anything wrong with what I have now? I assure you it's very readable.Note: In this case each orb is completely responsible for itself only so infinitely many orbs can be added. There are other methods and classes which I have not shown for sake of space and simplicity.    public void draw(Graphics gBuffer, Graphics g, Image vm)    {        gBuffer.setColor(color);        gBuffer.fillOval(x - velocity, y - velocity, 40, 40);        gBuffer.setColor(Color.black);        gBuffer.drawOval(x - velocity, y - velocity, 40, 40);        gBuffer.drawImage(vm,0,0,this);                // Here is one point I am wondering about                long startTime = 0, lastTime;                long delay=50, delta;                lastTime = startTime = System.currentTimeMillis();                collision = false;        orbPhysics();        space.repaint();    }    public void orbPhysics()    {                // Here is another point I am unsure of                delay = 1;                delta = System.currentTimeMillis()-lastTime;                lastTime+=delta;                collisionPhysics(delta/1000);                startTime+=delay;        bouncePhysics(); // edge of screen bouncing method (not shown)    }         // variables not shown    public void collisionPhysics(double dt)    {        ArrayList orbs = Space.orbList;        el = 1;        for(Orb orb : orbs)        {            r1 = radius;            m1 = radius * radius;            x1 = x + diameter/2;            y1 = y + diameter/2;            vx1 = xv;            vy1 = yv;                     Orb other = orb;               r2 = other.getRadius();            m2 = other.getRadius() * other.getRadius();            x2 = other.getX() + other.getDiameter()/2;            y2 = other.getY() + other.getDiameter()/2;            vy2 = other.getVelocityY();                  if(x1!=x2 && y1!=y2)    // I don't know if there is a better way to test orbs for equality         {            dx = x1-x2;            dy = y1-y2;                     d = (Math.sqrt(dx*dx+dy*dy));                                  if(d < r1+r2)                     {                       vp1 = vx1*dx/d + vy1*dy/d;                       vp2 = vx2*dx/d + vy2*dy/d;                                       // Here is another point I am unsure of                                       ddt = (r1+r2)/(vp1+vp2);                                             if(ddt > dt)                                              ddt = 0;                                       x1-=vx1*ddt;                                       y1-=vy1*ddt;                                       x2-=vx2*ddt;                                       y2-=vy2*ddt;                                   vp1 = vx1*dx/d + vy1*dy/d;                                   vp2 = vx2*dx/d + vy2*dy/d;                                   collision = true;                                   otherOrb = other;                     }                                if(collision)                     {                                   ax = dx/d;                                   ay = dy/d;                                   va1 = vx1*ax + vy1*ay;                                   vb1 = -vx1*ay + vy1*ax;                                   va2 = vx2*ax + vy2*ay;                                   vb2 = -vx2*ay + vy2*ax;                                   vaP1 = va1 + (1+el)*(va2-va1)/(1+m1/m2);                                   vaP2 = va2 + (1+el)*(va1-va2)/(1+m2/m1);                                   vx1 = vaP1*ax-vb1*ay;                                   vy1 = vaP1*ay+vb1*ax;                                   vx2 = vaP2*ax-vb2*ay;                                   vy2 = vaP2*ay+vb2*ax;                                   xv = vx1;                                   yv = vy1;                                   otherOrb.setVelocityX();                                   otherOrb.setVelocityY();                                   collision = false;            }         }      }   } Title: Re: 2D Collision Post by: Fu-Kwun Hwang on May 18, 2008, 10:09:32 pm dt =(r1+r2-d)/(vp1+vp2);// the collision should have occurred at t-dt (Actually this is also an approximation).However, your formula is ddt=(r1+r2)/(vp1+vp2);Please check out http://www.phy.ntnu.edu.tw/ntnujava/index.php?topic=4.msg15#msg15------------------------------------------------------------------------------------------------------------------I did not write java code directly since I knew about EJS. Because I use it to create java simulation (It will save me a lot of time).I am going to show you the way I used to create java simulation:public class javafilename extends java.applet.Applet implements Runnable{...   public void start(){      //Start animating!      if (animThread == null) {         animThread = new Thread(this);         animThread.start();      }      //Remember the starting time. of thread      lastTime=startTime = System.currentTimeMillis();   }    public void stop() {      //Stop the animating thread.      animThread = null;      running=false;   }   public void run() {      //Just to be nice, lower this thread's priority      Thread.currentThread().setPriority(Thread.MIN_PRIORITY);      //This is the animation loop.      while (Thread.currentThread() == animThread) {         //Advance the animation frame. with delta time         delta=System.currentTimeMillis()-lastTime;         lastTime+=delta;         if(running)advanced(delta/1000.);          startTime+=delay;         try {            animThread.sleep(Math.max(0,startTime-System.currentTimeMillis()));         } catch (InterruptedException e) {            break;         }      }   }   void advanced(double dt){// code to move particle from t to t+dt         ...        }...} Title: Re: 2D Collision Post by: ObsessedOne on May 21, 2008, 09:37:16 am Hello again,I have been trying to understand your code, but I know very little since I'm just a first year Computer Science student. I have read all your messages but my greatest problem is understanding the identifiers. I have tried your time change methods and they no longer clutch, but they still aren't colliding well.What is vx0/vy0?How does the variable "time" affect the program?What is the difference between dt and ddt?Why is delta divided by 1000 when it is passed?Does pauseID being equal to 1 indicate a collision?How is vn1/vn2 used?What is eta? (elasticity/energy?)Here is my program since the last post:    public Orb(Space s, int orbX, int orbY, int diameter, int speed)    {       space = s;       x = orbX;       y = orbY;       radius = diameter/2;       velocity = speed;       xMax = space.getAppletWidth()-diameter;       yMax = space.getAppletHeight()-diameter;     // This is not updated. I'm assuming it's supposed to only initialize.         time = 0;        delay = 50;        startTime = 0;        lastTime = startTime = System.currentTimeMillis();    }        public void draw(Graphics gBuffer, Image vm)    {         // This is updated every time the ball moves. I'm assuming this is correct.                  delta = System.currentTimeMillis()-lastTime;          lastTime += delta;          orbPhysics(delta);          startTime += delay;        space.repaint();    }     public void orbPhysics(double dt)   {               dt/=1000;               ArrayList orbs = space.getOrbList();      el = 1;            for(Orb orb : orbs)      {               Orb other = orb;                  if(x1!=x2 && y1!=y2)         {               dx = x1-x2;            dy = y1-y2;                     d = (Math.sqrt(dx*dx+dy*dy));                          if(d < r1+r2)             {                vp1 = vx1*dx/d + vy1*dy/d;                vp2 = vx2*dx/d + vy2*dy/d;                 // I'm not sure if this is the way to move the particles. I use x and y for their coordinates                                ddt = (r1+r2-d)/(vp1+vp2);                if(ddt > dt)                   ddt = 0;                x1-=vx1*ddt;                y1-=vy1*ddt;                x2-=vx2*ddt;                y2-=vy2*ddt;                x = (int)x1-radius;                y = (int)y1-radius;                other.setX((int)x2-other.getRadius());                other.setY((int)y2-other.getRadius());                                collision = true;            otherOrb = other;             }                          if(collision)         {            ax = dx/d;            ay = dy/d;            va1 = vx1*ax + vy1*ay;            vb1 = -vx1*ay + vy1*ax;            va2 = vx2*ax + vy2*ay;            vb2 = -vx2*ay + vy2*ax;            vaP1 = va1 + (1+el)*(va2-va1)/(1+m1/m2);            vaP2 = va2 + (1+el)*(va1-va2)/(1+m2/m1);            vx1 = vaP1*ax - vb1*ay;            vy1 = vaP1*ay + vb1*ax;            vx2 = vaP2*ax - vb2*ay;            vy2 = vaP2*ay + vb2*ax;                                // I think they should be moved forward in time here.            xv = vx1;            yv = vy1;            otherOrb.setVelocityX(vx2);            otherOrb.setVelocityY(vy2);            collision = false;         }      }   } } Title: Re: 2D Collision Post by: Fu-Kwun Hwang on May 21, 2008, 05:11:44 pm What is vx0/vy0? Because user can change the coordinate system, vx0,vy0 is the offset when changing the system. In your case, both of them will be 0.How does the variable "time" affect the program? time stored the real time value in second. it will starts to count when you click Start button. What is the difference between dt and ddt?dt is the time step in second.ddt is used for correct the time step, because when you detect two particle collide (d12We need to move time backward to d12==r1+r2 and ddt is the time needed to move particle backward.Did you read the posted message I have suggested ?Why is delta divided by 1000 when it is passed?delta is the time in milli-second (ms).Does pauseID being equal to 1 indicate a collision?If the checkbox cont. is not checked, the simulation will paused when collision occurred. How is vn1/vn2 used?Calculate the normal components of the velocity.What is eta? (elasticity/energy?)Yes. for in-elastic collision. it can be ranged between 0-1.The way you are coding is not the standard way. You should used the method I have suggested (which will give you almost the same simulation regarding different computer speed). Title: Re: 2D Collision Post by: ObsessedOne on May 22, 2008, 10:25:33 am Yes! I have it!Once I understood what the difference between dt and ddt was I understood everything perfectly. Now I will concentrate on efficiency over readability.Thank you very much Professor Hwang! Title: Re: 2D Collision Post by: ObsessedOne on May 26, 2008, 04:53:10 am Sorry to ask a non-physics related question, but how did you set the coordinates for your Choice menus? Mine default to the top center of my applet. Title: Re: 2D Collision Post by: Fu-Kwun Hwang on May 26, 2008, 08:47:54 am You need to set the LAYOUT for the applet. Please search with "applet layout". Title: Re: 2D Collision Post by: gap89 on June 10, 2008, 04:16:41 pm Hello Professor.Normally we are calculating the resultant vector from the initial velocity. Is it possible to do it the inverse way? assuming that the second object is stationary. Which just means I am trying to calculate the vector needed to collide with a stationary object to push the second object in a specific direction. Title: Re: 2D Collision Post by: Fu-Kwun Hwang on June 10, 2008, 11:55:37 pm Yes. You can!Write down the equation for conservation of momentum and conservation of energy, then solve it! Title: Re: 2D Collision Post by: gap89 on June 11, 2008, 02:13:07 pm Hmm.. I am still quite lost.I tried doing the inverse way by using the equations you have given, as I am using it for programming too, but it was hard to get the answer.Since object 2 is stationary, va2 and vb2 should be 0.Assuming I know what is the final vx2 and vx1, and also getting vap1 = 0.05*va1 ( ed = 0.9 ), vap2 = 0.95 * va1, so how do I continue from here? Or I can't do it this way? Title: Re: 2D Collision Post by: Fu-Kwun Hwang on June 11, 2008, 05:06:44 pm You should derive new equations instead of working from the equations in the current simulation.It is a different problem and the equations will be different.Please try to derive the equation from conservation of momentum and conservation of energy.And solve the combined equations.If your condition is push the second into a specific direction and no more, there are many possible solution (not just one).Because for 2D case, you only have 3 equations. But you have 5 unknown variables. Title: Re: 2D Collision Post by: HaydenG on June 18, 2008, 01:11:51 pm Hi, Im sorry to bother you buy could you please tell me what is wrong with this equationI apologize im not very good at programmingPublic Type PhysObj    X As Double    Y As Double    Xv As Double    Yv As Double    m As Integer 'mass    r As Integer 'radiusEnd TypePublic Function BallTouch(a As PhysObj, b As PhysObj, ed As Integer)    Dim dx As Double    Dim dy As Double    Dim d As Double    Dim ax As Double    Dim ay As Double    Dim ava As Double    Dim avb As Double    Dim bva As Double    Dim bvb As Double    Dim vapa As Double    Dim vapb As Double    Dim vpa As Double    Dim vpb As Double    Dim dt As Double    dx = a.X - b.X    dy = a.Y - b.Y    d = Sqr((dx * dx) + (dy * dy))    ax = dx / d    ay = dy / 2    ava = (a.Xv * ax) + (b.Yv * ay)     avb = (-a.Xv * ay) + (a.Yv * ax)     bva = (b.Xv * ax) + (b.Yv * ay)     bvb = (-b.Xv * ay) + (b.Yv * ax)     vapa = ava + (1 + ed) * (bva - ava) / (1 + (a.m / b.m))     vapb = bva + (1 + ed) * (ava - bva) / (1 + (b.m / a.m))     vpa = (a.Xv * dx) / d + (a.Yv * dy) / d     vpb = (b.Xv * dx) / d + (b.Yv * dy) / d     dt = (a.r + b.r - d) / (vpa + vpb)         If d < a.r Then     a.X = a.X - (a.Xv * dt)     b.X = b.X - (b.Xv * dt)     a.Y = a.Y - (a.Yv * dt)     b.Y = b.Y - (b.Yv * dt)     a.Xv = vapa * ax - avb * ay     a.Yv = vapa * ay + avb * ax     b.Xv = vapb * ax - bvb * ay     b.Yv = vapb * ay + bvb * ax     a.X = a.X + (a.Xv * dt)     b.X = b.X + (b.Xv * dt)     a.Y = a.Y + (a.Yv * dt)     b.Y = b.Y + (b.Yv * dt)    End If        End FunctionThank you ;D Title: Re: 2D Collision Post by: Fu-Kwun Hwang on June 18, 2008, 07:31:06 pm Why ay = dy / 2 ??? Title: Re: 2D Collision Post by: saeky123 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? Title: Re: 2D Collision Post by: Fu-Kwun Hwang 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 collisionsfor(int i=0;i 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)); } Title: Re: 2D Collision Post by: Fu-Kwun Hwang 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 (http://www.phy.ntnu.edu.tw/ntnujava/index.php?topic=120.0)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 (http://www.phy.ntnu.edu.tw/ntnujava/index.php?topic=4.msg15#msg15) Title: Re: 2D Collision Post by: slenzi on January 29, 2009, 12:15:05 am Thanks for the reply. I think I found the problem. I removed the if ddt > 0 and it seems to work.Quote from: Fu-Kwun Hwang on January 28, 2009, 10:51:17 amYou did not really solve the problem. You just ignore it.latest 2D collision created with EJS (http://www.phy.ntnu.edu.tw/ntnujava/index.php?topic=120.0)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 (http://www.phy.ntnu.edu.tw/ntnujava/index.php?topic=4.msg15#msg15) Title: Re: 2D Collision Post by: Fu-Kwun Hwang on January 29, 2009, 08:05:11 am You can change it to if(ddt>=0) Title: Re: Java Code for collision in 2D Post by: ashmpatel on April 28, 2009, 09:40:53 pm 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 likeva1 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);Quote from: Fu-Kwun Hwang on May 11, 2005, 07:03:51 amDue 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,y2dx=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+r20, i.e. x2>x1: it will require vx1>vx2 for collision to happened.2. if dx<0, i.e. x20)ddt=0.;       x1-=vx1*ddt;   y1-=vy1*ddt;      x2-=vx2*ddt;   y2-=vy2*ddt;      r12= sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));      //calculate component of velocity      cs=(x2-x1)/r12;   sc=(y2-y1)/r12;      vp1=vx1*cs+vy1*sc;      vp2=vx2*cs+vy2*sc;      //  normal components do not change      double vn1=vx1*sc-vy1*cs;      double vn2=vx2*sc-vy2*cs;      //calculate component of velocity in original X,Y coordinate      double px1=vp1*cs; double py1=vp1*sc;      double px2=vp2*cs; double py2=vp2*sc;      double nx1=vn1*sc; double ny1=-vn1*cs;      double nx2=vn2*sc; double ny2=-vn2*cs;            topspeedx =  px1+nx1;      topspeedy =  py1+ny1;      topbirspeedx =  px2+nx2;      topbirspeedy =  py2+ny2;                     int i=2;      top.center = CGPointMake(top.center.x + i*topspeedx, top.center.y + i*topspeedy);      topbir.center = CGPointMake(topbir.center.x + i*topbirspeedx, topbir.center.y + i*topbirspeedy);          } Title: Re: 3D Collision Post by: volpesfuggente on September 10, 2010, 05:40:28 pm Hi!I have some problems to manage 3D Collisions!!!I try to transform this 2D collision detection into 3d collision detection, but I have some problems to compute the dt!!!Sometimes, I have dt>>1.Anyone has some simple ideas to transform this 2d collision to 3d collision detection?Thanks to all. Title: Re: 2D Collision Post by: Fu-Kwun Hwang on September 10, 2010, 08:57:42 pm Please write down how you did it in detail so that we can discuss it base on your calculation.The required condition is $v*dt< r$ where $r$ is the radius of the ball. Title: Re: 2D Collision Post by: volpesfuggente on September 10, 2010, 10:19:52 pm Code:                float[] center1=p1.getCenter();        float[] center2=p2.getCenter();        float[] velocity1=p1.getVelocity();        float[] velocity2=p2.getVelocity();        short r1=p1.getRadius();        short r2=p2.getRadius();        float modVelocity1=p1.getVelocityModule();        float modVelocity2=p2.getVelocityModule();                            float dx21 = (center2[0]-center1[0]);            float dy21 = (center2[1]-center1[1]);            float dz21 = (center2[2]-center1[2]);                    float distance = (float) Math.sqrt(dx21*dx21+dy21*dy21+dz21*dz21);                        if (distance<((r1+r2))){                                        // Unit vector in the direction of the collision                float ax=((dx21/distance)), ay=((dy21/distance)), az=((dz21/distance));                float alfa=0;                                                        BigDecimal bg = new BigDecimal((velocity1[0]*dx21+velocity1[1]*dy21+velocity1[2]*dz21)/(modVelocity1*distance));                         bg = bg.setScale(3, BigDecimal.ROUND_HALF_UP);                         alfa=(float) Math.acos(bg.doubleValue()); // angle between velocity vector and distance vector                                                                         float alfaX1=(float) Math.acos((dx21)/(distance));                float alfaY1=(float) Math.acos((dy21)/(distance));                float alfaZ1=(float) Math.acos((dz21)/(distance));                                float modVa1=(float) (Math.abs(modVelocity1)*Math.cos(alfa));                float vax1=(float) (Math.abs(modVa1)*Math.cos(alfaX1));                float vay1=(float) (Math.abs(modVa1)*Math.cos(alfaY1));                float vaz1=(float) (Math.abs(modVa1)*Math.cos(alfaZ1));                                                            float vbx1=velocity1[0]-vax1;                float vby1=velocity1[1]-vay1;                float vbz1=velocity1[2]-vaz1;                                float beta=0;                                        BigDecimal bg = new BigDecimal((velocity2[0]*dx12+velocity2[1]*dy12+velocity2[2]*dz12)/(modVelocity2*distance));                         bg = bg.setScale(3, BigDecimal.ROUND_HALF_UP);                         beta=(float) Math.acos(bg.doubleValue()); // angle between velocity vector and distance vector                                                    float alfaX2=(float) Math.acos((dx12)/(distance));                float alfaY2=(float) Math.acos((dy12)/(distance));                float alfaZ2=(float) Math.acos((dz12)/(distance));                                //Velocity component along the distance vector between the 2 balls                float modVa2= (float) (Math.abs(modVelocity2)*Math.cos(beta));                float vax2=(float) (Math.abs(modVa2)*Math.cos(alfaX2));                float vay2=(float) (Math.abs(modVa2)*Math.cos(alfaY2));                float vaz2=(float) (Math.abs(modVa2)*Math.cos(alfaZ2));                                float vbx2=velocity2[0]-vax2;                float vby2=velocity2[1]-vay2;                float vbz2=velocity2[2]-vaz2;                float vxx21 =(vax2-vax1);                float vyy21 =(vay2-vay1);                float vzz21 =(vaz2-vaz1);                float modDiffVelocity=(float) Math.sqrt(vxx21*vxx21+vyy21*vyy21+vzz21*vzz21);                                float va1t=(velocity1[0]*ax+velocity1[1]*ay+velocity1[2]*az);                float va2t=(velocity2[0]*ax+velocity2[1]*ay+velocity2[2]*az);                dt = ((r1+r2-distance)/modDiffVelocity);            I tryed to use the polar coordinates to manage this problem in 3D.Any ideas? Title: Re: 2D Collision Post by: volpesfuggente on September 10, 2010, 10:22:42 pm time_step = 1v = 0.01R=2So, v*time_step