NTNUJAVA Virtual Physics LaboratoryEnjoy the fun of physics with simulations! Backup site http://enjoy.phy.ntnu.edu.tw/ntnujava/
June 21, 2018, 11:36:27 pm

Last chance is the best chance. ...Wisdom

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

Offline

Posts: 4

 « Embed this message Reply #120 on: June 30, 2009, 05:11:45 pm » posted from:Falls Church,Virginia,United States

hello Prof,
i have attached a doc file it contain a detail info about the problem to be solved.

thnx.
 *** There are 1 more attached files. You need to login to acces it! Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #121 on: July 01, 2009, 09:33:27 am » posted from:Taipei,T\'ai-pei,Taiwan

I created the following applet. It is similar to what you want.
You can change initial positions with different initialization code and add rules for your game.

You can drag from the center of the blue particle to change it's velocity when it is in paused state.
The blue particle will start to move when you release the mouse.
You can change the friction coefficient mu and elastic coefficient k.
k=1 means elastic collision without energy. k<1 then energy is loss due to collision.

Because the particle move in the same direction when there is no collision.
The friction force $F=\mu N= \mu m g$, from $F=ma$
The energy loss is $\vec{F}\cdot d\vec{s}= F d$ where d is the distance traveled.
d can be calculated between each time step.
And kinetic energy will be loss due to friction. $\tfrac{1}{2}mv'^2=\tfrac{1}{2}mv^2- F d$
So I re-calculate velocity after each time step.
And if the right hand side become smaller than zero, it means that the particle should have been stopped.
(So velocity has to be set to zero).

I think I should only help you from the physics point of view.
The rest work should be your job, waiting for you to finish it.

Embed a running copy of this simulation

Embed a running copy link(show simulation in a popuped window)
Full screen applet or Problem viewing java?Add http://www.phy.ntnu.edu.tw/ to exception site list
• Please feel free to post your ideas about how to use the simulation for better teaching and learning.
• Post questions to be asked to help students to think, to explore.
• Upload worksheets as attached files to share with more users.
Let's work together. We can help more users understand physics conceptually and enjoy the fun of learning physics!
 Logged
rahulpawar
Newbie

Offline

Posts: 4

 « Embed this message Reply #122 on: July 01, 2009, 05:32:39 pm » posted from:Norway,South Carolina,United States

hello prof,
Thank you for your help and guidance. I'll soon complete the project and inform you.
Thank you again !
 Logged
PrabhuKumar
Newbie

Offline

Posts: 1

 « Embed this message Reply #123 on: July 17, 2009, 10:21:07 pm » posted from:Bangalore,Karnataka,India

Hello Professor!

Thank you for all that you have shared and helped people understand these concepts with more clarity. I recently started looking into graphics on Windows Mobile phones and thanks to you I was able to come up with a colliding marbles program pretty quickly. If you are interested here is the link:

Sometimes there is a problem with the program. The balls will stick or completely disappear from the screen. But it happens very rarely, maybe around 1 in 30 times. I haven't yet looked deeply into the problem. Well, that is my next task (:

Thank you again and I really appreciate your work.
Prabhu
 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #124 on: July 18, 2009, 08:30:02 am » posted from:Taipei,T\'ai-pei,Taiwan

There is an assumption for all the above discussion:
The time step dt need to be smaller enough (which is depend on velocity V and diameter of the ball R).
V*dt<< R (　dt<0.1*R/V should be fine).

If V*dt ≒ R , the approximation used in the calculation (finding the time collision really occurred) is not valid.

So you should adjust time step (or set maximum value for V) to satisfy the above condition.
 Logged
vanmobi
Newbie

Offline

Posts: 4

 « Embed this message Reply #125 on: September 03, 2009, 10:04:16 am » posted from:Hallandale,Florida,United States

When m1 = m2, is it normal that the sum of the speed of the 2 balls does not remain constant over time?

 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #126 on: September 03, 2009, 11:36:13 am » posted from:Taipei,T\'ai-pei,Taiwan

Conservation of momentum require
$m_1 \vec{v_1}+m_2\vec{v_2}=m_1 \vec{v_1}'+m_2\vec{v_2}'$
If $m_1=m_2$, it reduced to
$\vec{v_1}+\vec{v_2}= \vec{v_1}'+\vec{v_2}'$

Velocity is a vector which is not the same a speed!
You can check that the sum of x (or y) component of velocity should be the same before and after collision (when $m_1=m_2$)
 Logged
Thomas
Newbie

Offline

Posts: 2

 « Embed this message Reply #127 on: January 01, 2010, 11:50:19 pm » posted from:Leicester,Leicester,United Kingdom

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
*******************

Please note that I modified the code in my routines now such as to work for (partially) inelastic collisions as well. This was simply achieved by subtracting the velocity of the center of mass from the final velocities for the elastic collision case, multiplying this by the restitution coefficient (which is an additional input parameter) and adding the velocity of the center of mass on again.

Thomas
 Logged
mubbashar
Newbie

Offline

Posts: 1

hello professor

// 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

why we need vb1 and vb2 ?? and also what is your means by undo projection..
actually sir i am doing work on molecular dynamics in gas and when particals are collide we use your model of 2d collision is this correct for us to use these equations at the time of collision ??
 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #129 on: January 05, 2010, 10:20:56 pm » posted from:Taipei,T\'ai-pei,Taiwan

In the real world, time move continuously.
However, we can not do the calculation continuously. It is always a finite time step (no matter how small it might be).

The time step dt is the same during the simulation.
However, collision often occurred in between time steps (between time t to t+dt).

We tried to detect if two object overlap each to know colllision should have occurred.
Then, we need to find the exact time when collision occurred.
If this 2D collision, we use an approximation method to find the time when collision occurred.
Support the rasius of two particles are r1 and r2, and the distance between two center is d.
And the relative velocity along two center is vp,
then we move back time step ddt=(d-(r1+r2))/vp to find the time collision occurred.
(The above approximation is only good if the relative velocity is small enrough, i.e. vp*dt<
After we take care of collision, we need to move time forward ddt again.
 Logged
lookang
Hero Member

Offline

Posts: 1787

http://weelookang.blogspot.com

 « Embed this message Reply #130 on: January 05, 2010, 10:28:56 pm »

The time step dt is the same during the simulation.
However, collision often occurred in between time steps (between time t to t+dt).

We tried to detect if two object overlap each to know collision should have occurred.
Then, we need to find the exact time when collision occurred.
If this 2D collision, we use an approximation method to find the time when collision occurred.
Support the radius of two particles are r1 and r2, and the distance between two center is d.
And the relative velocity along two center is vp,
then we move back time step ddt=(d-(r1+r2))/vp to find the time collision occurred.
(The above approximation is only good if the relative velocity is small enough, i.e. vp*dt<
After we take care of collision, we need to move time forward ddt again.

This is a computational logic that i only appreciated and understood after using Ejs to make simulations, because i was trying to do the same thing. "detect if two object overlap each to know collision should have occurred."

In Ejs i think it is called Event Handlers.
Thanks!
it is good explanation.
 Logged
hellmaster
Newbie

Offline

Posts: 1

 « Embed this message Reply #131 on: March 20, 2010, 11:44:11 am » posted from:Chengdu,Sichuan,China

This is helpful, keep learning. Thanks
 Logged
jenny.smith
Newbie

Offline

Posts: 3

 « Embed this message Reply #132 on: July 23, 2010, 08:07:04 pm » posted from:Mumbai,Maharashtra,India

If you do not believe that the bounding box collision would be good for your preflight you should try the circle of its bounding box .. then it really does not matter. Check two circles overlap is much easier to see, too, at least in my opinion.
 Logged
ursan
Newbie

Offline

Posts: 2

 « Embed this message Reply #133 on: September 05, 2010, 03:40:54 am » posted from:Istanbul,Istanbul,Turkey

Hi all.
collision is a problem when I do the formula and the balls is stopped. do not understand why they stopped. I have the following code.

double  x1=ball.center.x,  y1=ball.center.y,  x2=balltwo.center.x,  y2=balltwo.center.y,
vx1=ballspeedx,  vy1=ballspeedy,  vx2=balltwospeedx,  vy2=balltwospeedy;

double dx = x2-x1, dy = y2-y1;
// where x1,y1 are center of ball1, and x2,y2 are center of ball2
double distance = 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+1)*(va2-va1)/(1+1);
double vaP2=va2 + (1+1)*(va1-va2)/(1+1);
// 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

ballspeedx =  vx1;
ballspeedy =  vy1;
balltwospeedx =  vx2;
balltwospeedy =  vx2;

ball.center = CGPointMake(ball.center.x + ballspeedx, ball.center.y + ballspeedy);
balltwo.center = CGPointMake(topbir.center.x + balltwospeedx, topbir.center.y + balltwospeedy);
or

double  x1=ball.center.x,  y1=ball.center.y,  x2=balltwo.center.x,  y2=balltwo.center.y,
vx1=ballspeedx,  vy1=ballspeedy,  vx2=balltwospeedx,  vy2=balltwospeedy;

double dx = x2-x1, dy = y2-y1;
// where x1,y1 are center of ball1, and x2,y2 are center of ball2
double distance = 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+1)*(va2-va1)/(1+1);
double vaP2=va2 + (1+1)*(va1-va2)/(1+1);
// 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

ballspeedx =  vx1;
ballspeedy =  vy1;
balltwospeedx =  vx2;
balltwospeedy =  vx2;

dx=x2-x1, dy=y2-y1; d=sqrt(dx*dx+dy*dy);

double vp1= vx1 *dx/d+vy1*dy/d;
double vp2= vx2*dx+vy2*dy/d;
double dt =(r1+r2-d)/(vp1+vp2);

x1-= vx1*dt;
y1 -= vy1*dt;
x2-=vx2*dt;
y2-=vy2*dt;

ball.center = CGPointMake(x1, y1);
balltwo.center = CGPointMake(x2, y2);

x1+= vx1*dt;
y1+=vy1*dt;
x2+=vx2*dt;
y2+=vy2*dt;

ball.center = CGPointMake(x1, y1);
balltwo.center = CGPointMake(x2, y2);

ball.center = CGPointMake(ball.center.x + ballspeedx, ball.center.y + ballspeedy);
balltwo.center = CGPointMake(topbir.center.x + balltwospeedx, topbir.center.y + balltwospeedy);

the same in both programs. example:
ballspeedx=0;ballspeedy=4;balltwospeedx=0;balltwospeedy=-4;

3. After the collision the ball is stopped and disappear from the screen. vx1 ,vy1,vx2,vy2 values is -2145444...
 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #134 on: September 05, 2010, 09:45:39 pm » posted from:,,Taiwan

The above code works under the following assumption: v*dt<< R, where R is the radius of the ball.
It means that the time step need to be chose properly.
 Logged
ursan
Newbie

Offline

Posts: 2

 « Embed this message Reply #135 on: September 06, 2010, 01:15:28 am » posted from:Istanbul,Istanbul,Turkey

I'm sorry I did not understand. v What is the speed of the ball. vx1,vx2,vy1 or vy2.  complate code is;

-(void) tophareket {
ballspeedx=0; ballspeedy=4; balltwospeedx=0; balltwospeedy=-4;

// top top1'e değerse
if(sqrt(pow((balltwo.center.x-ball.center.x),2)+pow((balltwo.center.y-ball.center.y),2))<38)
{
double  r1=19, r2=19, m1=1, m2=1, x1=ball.center.x,  y1=ball.center.y,  x2=balltwo.center.x,  y2=balltwo.center.y,
vx1=ballspeedx,  vy1=ballspeedy,  vx2=balltwospeedx,  vy2=balltwospeedy;

double dx = x2-x1, dy = y2-y1;
// where x1,y1 are center of ball1, and x2,y2 are center of ball2
double distance = 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+1)*(va2-va1)/(1+1);
double vaP2=va2 + (1+1)*(va1-va2)/(1+1);
// 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

ballspeedx =  vx1;
ballspeedy =  vy1;
balltwospeedx =  vx2;
balltwospeedy =  vx2;

dx=x2-x1, dy=y2-y1; d=sqrt(dx*dx+dy*dy);

double vp1= vx1 *dx/d+vy1*dy/d;
double vp2= vx2*dx+vy2*dy/d;
double dt =(r1+r2-d)/(vp1+vp2);

x1-= vx1*dt;
y1 -= vy1*dt;
x2-=vx2*dt;
y2-=vy2*dt;

ball.center = CGPointMake(x1, y1);
balltwo.center = CGPointMake(x2, y2);

x1+= vx1*dt;
y1+=vy1*dt;
x2+=vx2*dt;
y2+=vy2*dt;

ball.center = CGPointMake(x1, y1);
balltwo.center = CGPointMake(x2, y2);

ball.center = CGPointMake(ball.center.x + ballspeedx, ball.center.y + ballspeedy);
balltwo.center = CGPointMake(topbir.center.x + balltwospeedx, topbir.center.y + balltwospeedy);
}

and I tried the java programs you provide, tenth the collision happened. I wonder where I made a mistake?

-(void) tophareket {

// top top1'e değerse
if(sqrt(pow((topbir.center.x-top.center.x),2)+pow((topbir.center.y-top.center.y),2))<41)
{
double alpha,  m1=1,  m2=1,  r1=19,  r2=19,
x1=top.center.x,  y1=top.center.y,  x2=topbir.center.x,  y2=topbir.center.y,
vx1=topspeedx,  vy1=topspeedy,  vx2=topbirspeedx,  vy2=topbirspeedy,;

double r12=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
double cs=(x2-x1)/r12;   double sc=(y2-y1)/r12;
double vp1=vx1*cs+vy1*sc;
double vp2=vx2*cs+vy2*sc;
// back to collision time
double ddt=(r1+r2-r12)/(vp1-vp2);
if(ddt>0)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);

}

 Logged
volpesfuggente
Newbie

Offline

Posts: 4

 « Embed this message Reply #136 on: September 10, 2010, 05:40:28 pm » posted from:Montefalco,Umbria,Italy

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.
 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #137 on: September 10, 2010, 08:57:42 pm » posted from:,,Taiwan

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.
 Logged
volpesfuggente
Newbie

Offline

Posts: 4

 « Embed this message Reply #138 on: September 10, 2010, 10:19:52 pm » posted from:Montefalco,Umbria,Italy

Code:
float[] center1=p1.getCenter();
float[] center2=p2.getCenter();
float[] velocity1=p1.getVelocity();
float[] velocity2=p2.getVelocity();
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?
 Logged
volpesfuggente
Newbie

Offline

Posts: 4

 « Embed this message Reply #139 on: September 10, 2010, 10:22:42 pm » posted from:Montefalco,Umbria,Italy

time_step = 1

v = 0.01

R=2

So, v*time_step<R1

 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #140 on: September 10, 2010, 11:50:11 pm » posted from:,,Taiwan

I do not understand the way you defined those angle?
I would suggest you use (x,y,z) coordinate.

Assume $\vec{r_a}$ and $\vec{r_b}$ are center of those two balls. And the radius are $R_a,R_b$.
Let $\vec{d}= \vec{r_a}-\vec{r_b}$ which is the relative vector between two centers.
Collision occurred if the length $|\vec{d}|:
The next step is to find two components of velocity vectors $\vec{V_a}=(V_{ax},V_{ay},V_{az}),\vec{V_b}=(V_{bx},V_{by},V_{bz})$:
1. velocity components parallel to $\vec{d}=(d_x,d_y,d_z)$
$\vec{V}_{ap}=\vec{V_a}\cdot \vec{d}/|\vec{d}|,\vec{V}_{bp}=\vec{V_b}\cdot \vec{d}/|\vec{d}|$
The time step to move backward $dt=\frac{R_a+R_b-|\vec{d}|}{|\vec{V}_{ap}-\vec{V}_{bp}|}$

Hints: how to calculate inner product $\vec{V_a}\cdot \vec{d}=V_{ax}*d_x+ V_{ay}*d_y+V{az}*dz$

2. velocity components perpendicular to $\vec{d}$
$\vec{V_{an}}=\vec{V_a}-\vec{V_{ap}}, \vec{V_{bn}}=\vec{V_b}-\vec{V_{bp}}$
The above two component will not change before and after collision

You can check out previous posted message. e.g. How to convert 2D collision into 1D

Just add one more component (z) if you want to transfer from 2D(x,y)to 3D(x,y,z).

It will be much easier if understand the meaning of inner product between two vectors- Help you find out projection of one vector into another vector.
 Logged
volpesfuggente
Newbie

Offline

Posts: 4

 « Embed this message Reply #141 on: September 14, 2010, 12:24:48 am » posted from:Campi Bisenzio,Toscana,Italy

I do not understand the way you defined those angle?
I would suggest you use (x,y,z) coordinate.

Assume $\vec{r_a}$ and $\vec{r_b}$ are center of those two balls. And the radius are $R_a,R_b$.
Let $\vec{d}= \vec{r_a}-\vec{r_b}$ which is the relative vector between two centers.
Collision occurred if the length math_failure (math_unknown_error): |\vec{d}|&lt;R_a+R_b :
The next step is to find two components of velocity vectors $\vec{V_a}=(V_{ax},V_{ay},V_{az}),\vec{V_b}=(V_{bx},V_{by},V_{bz})$:
1. velocity components parallel to $\vec{d}=(d_x,d_y,d_z)$
$\vec{V}_{ap}=\vec{V_a}\cdot \vec{d}/|\vec{d}|,\vec{V}_{bp}=\vec{V_b}\cdot \vec{d}/|\vec{d}|$
The time step to move backward $dt=\frac{R_a+R_b-|\vec{d}|}{|\vec{V}_{ap}-\vec{V}_{bp}|}$

Hints: how to calculate inner product $\vec{V_a}\cdot \vec{d}=V_{ax}*d_x+ V_{ay}*d_y+V{az}*dz$

2. velocity components perpendicular to $\vec{d}$
$\vec{V_{an}}=\vec{V_a}-\vec{V_{ap}}, \vec{V_{bn}}=\vec{V_b}-\vec{V_{bp}}$
The above two component will not change before and after collision

You can check out previous posted message. e.g. How to convert 2D collision into 1D

Just add one more component (z) if you want to transfer from 2D(x,y)to 3D(x,y,z).

It will be much easier if understand the meaning of inner product between two vectors- Help you find out projection of one vector into another vector.

Thank you very much, but I still have a problem.
I'm not sure that the bounce is correct...

This is my code:
Code:
float[] center1=p1.getCenter();
float[] center2=p2.getCenter();
float[] velocity1=p1.getVelocity();
float[] velocity2=p2.getVelocity();

float dx12 = (center1[0]-center2[0]);
float dy12 = (center1[1]-center2[1]);
float dz12 = (center1[2]-center2[2]);

float dx21 = (center2[0]-center1[0]);
float dy21 = (center2[1]-center1[1]);
float dz21 = (center2[2]-center1[2]);

float distance = (float) Math.sqrt(dx12*dx12+dy12*dy12+dz12*dz12);

if (distance<((r1+r2))){

float[] Va=p1.getVelocityComponent();
float[] Vb=p2.getVelocityComponent();

float[] D={dx12,dy12,dz12};
float[] Db={dx21,dy21,dz21};

float[] Vap= new float[3];
Vap[0]=Va[0]*D[0]/distance;
Vap[1]=Va[1]*D[1]/distance;
Vap[2]=Va[2]*D[2]/distance;

float[] Vbp= new float[3];
Vbp[0]=Vb[0]*Db[0]/distance;
Vbp[1]=Vb[1]*Db[1]/distance;
Vbp[2]=Vb[2]*Db[2]/distance;

float diff=(float) Math.sqrt((Vap[0]-Vbp[0])*(Vap[0]-Vbp[0])+(Vap[1]-Vbp[1])*(Vap[1]-Vbp[1])+(Vap[2]-Vbp[2])*(Vap[2]-Vbp[2]));

float dt=(r1+r2-distance)/(diff);

float[] Van = new float[3];
Van[0]=Va[0]-Vap[0];
Van[1]=Va[1]-Vap[1];
Van[2]=Va[2]-Vap[2];

float[] Vbn = new float[3];
Vbn[0]=Vb[0]-Vbp[0];
Vbn[1]=Vb[1]-Vbp[1];
Vbn[2]=Vb[2]-Vbp[2];

center1[0]-=Va[0]*dt;
center1[1]-=Va[1]*dt;
center1[2]-=Va[2]*dt;

center2[0]-=Vb[0]*dt;
center2[1]-=Vb[1]*dt;
center2[2]-=Vb[2]*dt;

dx12 = (center1[0]-center2[0]);
dy12 = (center1[1]-center2[1]);
dz12 = (center1[2]-center2[2]);

dx21 = (center2[0]-center1[0]);
dy21 = (center2[1]-center1[1]);
dz21 = (center2[2]-center1[2]);

distance = (float) Math.sqrt(dx12*dx12+dy12*dy12+dz12*dz12);
// Unit vector in the direction of the collision
double ax=dx12/distance, ay=dy12/distance, az=dz12/distance;

float[] Vap1= new float[3];
Vap1[0]=(float) (Va[0]*ax);
Vap1[1]=(float) (Va[1]*ay);
Vap1[2]=(float) (Va[2]*az);

float[] Vbp1= new float[3];
Vbp1[0]=(float) (Vb[0]*(-ax));
Vbp1[1]=(float) (Vb[1]*(-ay));
Vbp1[2]=(float) (Vb[2]*(-az));

float[] Van1 = new float[3];
Van1[0]=Va[0]-Vap1[0];
Van1[1]=Va[1]-Vap1[1];
Van1[2]=Va[2]-Vap1[2];

float[] Vbn1 = new float[3];
Vbn1[0]=Vb[0]-Vbp1[0];
Vbn1[1]=Vb[1]-Vbp1[1];
Vbn1[2]=Vb[2]-Vbp1[2];

float mass1=p1.getMass();
float mass2=p2.getMass();

float[] vaP1=new float[3];
vaP1[0]=(float) (Vap1[0] + (1+ed)*(Vbp1[0]-Vap1[0])/(1+mass1/mass2));
vaP1[1]=(float) (Vap1[1] + (1+ed)*(Vbp1[1]-Vap1[1])/(1+mass1/mass2));
vaP1[2]=(float) (Vap1[2] + (1+ed)*(Vbp1[2]-Vap1[2])/(1+mass1/mass2));

float[] vaP2=new float[3];
vaP2[0]=(float) (Vbp1[0] + (1+ed)*(Vap1[0]-Vbp1[0])/(1+mass2/mass1));
vaP2[1]=(float) (Vbp1[1] + (1+ed)*(Vap1[1]-Vbp1[1])/(1+mass2/mass1));
vaP2[2]=(float) (Vbp1[2] + (1+ed)*(Vap1[2]-Vbp1[2])/(1+mass2/mass1));

velocity1[0]=vaP1[0]-Van[0];
velocity1[1]=vaP1[1]-Van[1];
velocity1[2]=vaP1[2]-Van[2];

velocity2[0]=vaP2[0]-Vbn[0];
velocity2[1]=vaP2[1]-Vbn[1];
velocity2[2]=vaP2[2]-Vbn[2];

center1[0]+=velocity1[0]*dt;
center1[1]+=velocity1[1]*dt;
center1[2]+=velocity1[2]*dt;

center2[0]+=velocity2[0]*dt;
center2[1]+=velocity2[1]*dt;
center2[2]+=velocity2[2]*dt;

There is some problems with to compute the diff, because sometimes it is NaN...
There is any error in my code?
 « Last Edit: September 14, 2010, 12:26:56 am by volpesfuggente » Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #142 on: September 14, 2010, 08:52:50 am » posted from:Taipei,T'ai-pei,Taiwan

There must be some bug in your code:
Normally, NaN came from divided by zero or negative value inside sqrt root, etc.

The program should be able to provide the line number where the error occurs.
Find out the code which produce the error.
 Logged
zazz
Newbie

Offline

Posts: 1

 « Embed this message Reply #143 on: September 24, 2010, 09:45:07 pm » posted from:Detroit,Michigan,United States

Hi professor, quick question:

What dictates the direction of the normal vector? While i understand that it's perpendicular to the angle of collision(AoC), what determines whether its AoC+PI/2 or AoC-PI/2?

 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #144 on: September 25, 2010, 12:12:00 am » posted from:,,Taiwan

It does not matter as long as you use the same vector to convert normal component and parallel component back to final velocity after collision.

That is the beauty of vector analysis!

You can try it with either one, and you will find out that you will get the same result.
 Logged
lunayo
Newbie

Offline

Posts: 6

 « Embed this message Reply #145 on: October 07, 2010, 12:35:22 pm » posted from:Jakarta,Jakarta Raya,Indonesia

Sir, I'm implementing 2d collision on objective - c using opengl.
but it didn't work . if i didn't calculate and apply dt to ball 1 position (translation) , the ball is stuck together (but it is moving) .
but if i apply dt, the ball seems going messy when collideed. can you see what is going on with the code?
the variable dt can be minus when check through console, is it right?

Code:
BBPoint coliddeSpeed = [(BBStaticMarble*)sceneObject speed];
BBPoint collideeTranslation = [(BBStaticMarble*)sceneObject translation];

CGFloat r1,r2;
CGFloat dx=collideeTranslation.x-translation.x, dy=collideeTranslation.y-translation.y;
CGFloat d=sqrt(dx*dx+dy*dy);
//First calculate the component of velocity in the direction of (dx,dy)
CGFloat vp1= speed.x*dx/d+speed.y*dy/d;
CGFloat vp2= collideeSpeed.x*dx/d+collideeSpeed.y*dy/d;
//Collision should have happened dt before you have detected r1+r2
CGFloat 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
translation.x -= speed.x*dt;
translation.y -= speed.y*dt;
collideeTranslation.x -=collideeSpeed.x*dt;
collideeTranslation.y-=collideeSpeed.y*dt;

dx=collideeTranslation.x-translation.x, dy=collideeTranslation.y-translation.y;
// where x1,y1 are center of ball1, and x2,y2 are center of ball2
CGFloat distance = sqrt(dx*dx+dy*dy);
// Unit vector in the direction of the collision
CGFloat ax=dx/distance, ay=dy/distance;
// Projection of the velocities in these axes
CGFloat va1=(speed.x*ax+speed.y*ay), vb1=(-speed.x*ay+speed.y*ax);
CGFloat va2=(collideeSpeed.x*ax+speed.y*ay), vb2=(-collideeSpeed.x*ay+collideeSpeed.y*ax);
// New velocities in these axes (after collision): ed<=1,  for elastic collision ed=1
CGFloat ed = 0.8;
CGFloat vaP1=va1 + (1+ed)*(va2-va1)/(1+self.mass/collideeMass);
CGFloat vaP2=va2 + (1+ed)*(va1-va2)/(1+collideeMass/self.mass);
// Undo the projections
speed.x=vaP1*ax-vb1*ay;  speed.y=vaP1*ay+vb1*ax;// new vx,vy for ball 1 after collision
collideeSpeed.x=vaP2*ax-vb2*ay; collideeSpeed.y=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.
translation.x+= speed.x*dt;
translation.y+= speed.y*dt;
collideeTranslation.x+=collideeSpeed.x*dt;
collideeTranslation.x+=collideeSpeed.y*dt;

[(BBStaticMarble*)sceneObject setSpeed:collideeSpeed];
[(BBStaticMarble*)sceneObject setTranslation:collideeTranslation];
[(BBStaticMarble*)sceneObject setIsMarbleMoving:YES]
 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #146 on: October 07, 2010, 04:49:43 pm » posted from:Taipei,T'ai-pei,Taiwan

The problem could be due to the parameters used in the simulation.

The above model of calculation assume: the time step is small enough so that the distance move in each time step is smaller than the radius of both particles.

The problem you found much be due to the time step is too large or the velocity is too large.

1. r1 and r2 are about the same or similar order.
2. v_1 *dt<< r_1+r_2 , v_2*dt<< r_1+r_2
 Logged
lunayo
Newbie

Offline

Posts: 6

 « Embed this message Reply #147 on: October 08, 2010, 01:50:18 am » posted from:Jakarta,Jakarta Raya,Indonesia

Quote
The problem could be due to the parameters used in the simulation.

The above model of calculation assume: the time step is small enough so that the distance move in each time step is smaller than the radius of both particles.

The problem you found much be due to the time step is too large or the velocity is too large.

1. r1 and r2 are about the same or similar order.
2. v_1 *dt<< r_1+r_2 , v_2*dt<< r_1+r_2

What should i change if the velocity is too large or the time step is too large? (I'm using 60 frame per second in the simulation)
 Logged
Fu-Kwun Hwang
Hero Member

Offline

Posts: 3080

 « Embed this message Reply #148 on: October 08, 2010, 03:14:36 pm » posted from:Taipei,T'ai-pei,Taiwan

Make the velocity smaller or change the time step to smaller value.

May be you are updating the view 60frame per second.
You can make the time step 1/600 second, and update the view every 10 second.
So it is up to you to change the time step to any suitable precision you want.
 Logged
lunayo
Newbie

Offline

Posts: 6

 « Embed this message Reply #149 on: October 08, 2010, 04:04:36 pm » posted from:Jakarta,Jakarta Raya,Indonesia

Sir, why the dt can be result of nan? what can cause that? how to solve it?
and i found that when ball1 collideed with ball2 with mass1/mass2 = 1.0, velocity x ball1 200 , velocity x ball 2 -100 (moving opposite) and ed = 0.8, ball1 didn't bounce a bit, instead ball1 just moving forward.
 « Last Edit: October 08, 2010, 04:31:22 pm by lunayo » Logged
 Pages: 1 ... 3 4 [5] 6   Go Up
Last chance is the best chance. ...Wisdom