NTNUJAVA Virtual Physics Laboratory
Enjoy the fun of physics with simulations!
September 30, 2014, 04:44:10 pm *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
 
   Home   Help Search Login Register  
Like what you dislike of those things are imortant. ...Wisdom
Google Bookmarks Yahoo My Web MSN Live Netscape Del.icio.us FURL Stumble Upon Delirious Ask FaceBook

Pages: 1 ... 4 5 [6]   Go Down
  Print  
Author Topic: 2D Collision  (Read 394046 times)
0 Members and 2 Guests are viewing this topic. Click to toggle author information(expand message area).
Fu-Kwun Hwang
Administrator
Hero Member
*****
Offline Offline

Posts: 3056



WWW
«
Embed this message
Reply #150 on: October 08, 2010, 06:06:57 pm » posted from:Taipei,T'ai-pei,Taiwan

You have the following code
Code:
dt = (r1+r2-d)/(vp1-vp2);
What if vp1==vp2???


You also have the following code

Code:
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;

What if d==0???

It could also be other kind of bug in your code. You need to trace the code (find out value for variables) and try to find out the problem.
It is not easy to find the bug.  Good luck!
Logged
mediakitchen
Newbie
*
Offline Offline

Posts: 9


«
Embed this message
Reply #151 on: October 08, 2010, 11:12:46 pm » posted from:Wantage,Oxfordshire,United Kingdom

I am very pleased to have found this site and especially this thread. I am creating a ball based game in a language called Lua and have been trying to use your code as follows:

I have multiple balls in the game. The code is so close to working perfectly - just occasionally I get a badly behaved ball that appears to shoot off the screen extremely fast.

Would appreciate if you can spot any issues. I have a maximum speed of 14. Also please note I have a tempX and tempY property for each ball. Once I have checked for all the collisions with all the balls. I then set their actual screen x and y positions.

Hope you can help me identify any issues with my code.

Thanks

Paul

Code:

local function checkForCollisionWithBall( firstBallRef, secondBallRef )

  -- ------------------
  -- Set some constants
  -- ------------------

  local D = 14 -- Radius of ball
  local D2 = (2 * D) * (2 * D) -- Radius squared

 
  -- ---------------------------------------------
  -- Calculate distance between balls on both axis
  -- ---------------------------------------------
 
  local dx = secondBallRef.tempX - firstBallRef.tempX -- horizontal distance between the 2 balls
  local dy = secondBallRef.tempY - firstBallRef.tempY -- vertical distance between the 2 balls
 
 
  local dxy = (dx * dx) + (dy * dy)
 
  if (dxy < 0.00001) then
 
 
 
  return
 
  end
 
 
 
  if (dxy < D2) then
 
  -- --------------------
  -- We have a collision!
  -- --------------------
 
  -- ------------------------------------------------------------------------------
  -- We now perform the square root to calculate the distance between the two balls
  -- ------------------------------------------------------------------------------
 
  dxy = mSqrt(dxy)
 
  local cs = dx/dxy
  local sc = dy/dxy
 
  -- -----------------------------------------------------------
  -- Calculate component of velocity in the direction of (dx,dy)
  -- -----------------------------------------------------------
 
  local vp1 = firstBallRef.horizontalVelocity * cs + firstBallRef.verticalVelocity * sc
  local vp2 = secondBallRef.horizontalVelocity * cs + secondBallRef.verticalVelocity * sc
 
 
 
  local dt = (D + D - dxy) / (vp1 - vp2)
 
 
 
  firstBallRef.tempX = firstBallRef.tempX - (firstBallRef.horizontalVelocity * dt)
  firstBallRef.tempY = firstBallRef.tempY - (firstBallRef.verticalVelocity * dt)
 
 
 
 
  secondBallRef.tempX = secondBallRef.tempX - (secondBallRef.horizontalVelocity * dt)
  secondBallRef.tempY = secondBallRef.tempY - (secondBallRef.verticalVelocity * dt)
 
 
 
  dx = secondBallRef.tempX - firstBallRef.tempX -- horizontal distance between the 2 balls
  dy = secondBallRef.tempY - firstBallRef.tempY -- vertical distance between the 2 balls
 
  local distance = mSqrt(dx * dx + dy * dy)
  local ax = dx/distance
  local ay = dy/distance
 
 
 
  local va1 = (firstBallRef.horizontalVelocity * ax + firstBallRef.verticalVelocity * ay)
  local vb1 = (-1 * firstBallRef.horizontalVelocity * ay + firstBallRef.verticalVelocity * ax)
 
  local va2 = (secondBallRef.horizontalVelocity * ax + secondBallRef.verticalVelocity * ay)
  local vb2 = (-1 * secondBallRef.horizontalVelocity * ay + secondBallRef.verticalVelocity * ax)
 
 
 
  local vaP1 = va1 + (1 + 1) * (va2 - va1)/(1 + 1/1)
  local vaP2 = va2 + (1 + 1) * (va1 - va2)/(1 + 1/1)
 
 
  firstBallRef.horizontalVelocity = vaP1 * ax - vb1 * ay
  firstBallRef.verticalVelocity = vaP1 * ay + vb1 * ax
 
 
  secondBallRef.horizontalVelocity = vaP2 * ax - vb2 * ay
  secondBallRef.verticalVelocity = vaP2 * ay + vb2 * ax
 
 
 
  firstBallRef.tempX = firstBallRef.tempX + firstBallRef.horizontalVelocity * dt
  firstBallRef.tempY = firstBallRef.tempY + firstBallRef.verticalVelocity * dt
 
  secondBallRef.tempX = secondBallRef.tempX + secondBallRef.horizontalVelocity * dt
  secondBallRef.tempY = secondBallRef.tempY + secondBallRef.verticalVelocity * dt

 
  end
 
end



Logged
lunayo
Newbie
*
Offline Offline

Posts: 6


«
Embed this message
Reply #152 on: October 09, 2010, 02:57:47 am » posted from:Jakarta,Jakarta Raya,Indonesia

I am very pleased to have found this site and especially this thread. I am creating a ball based game in a language called Lua and have been trying to use your code as follows:

I have multiple balls in the game. The code is so close to working perfectly - just occasionally I get a badly behaved ball that appears to shoot off the screen extremely fast.

Would appreciate if you can spot any issues. I have a maximum speed of 14. Also please note I have a tempX and tempY property for each ball. Once I have checked for all the collisions with all the balls. I then set their actual screen x and y positions.

Hope you can help me identify any issues with my code.

Thanks

Paul

Code:

local function checkForCollisionWithBall( firstBallRef, secondBallRef )

  -- ------------------
  -- Set some constants
  -- ------------------

  local D = 14 -- Radius of ball
  local D2 = (2 * D) * (2 * D) -- Radius squared

 
  -- ---------------------------------------------
  -- Calculate distance between balls on both axis
  -- ---------------------------------------------
 
  local dx = secondBallRef.tempX - firstBallRef.tempX -- horizontal distance between the 2 balls
  local dy = secondBallRef.tempY - firstBallRef.tempY -- vertical distance between the 2 balls
 
 
  local dxy = (dx * dx) + (dy * dy)
 
  if (dxy < 0.00001) then
 
 
 
  return
 
  end
 
 
 
  if (dxy < D2) then
 
  -- --------------------
  -- We have a collision!
  -- --------------------
 
  -- ------------------------------------------------------------------------------
  -- We now perform the square root to calculate the distance between the two balls
  -- ------------------------------------------------------------------------------
 
  dxy = mSqrt(dxy)
 
  local cs = dx/dxy
  local sc = dy/dxy
 
  -- -----------------------------------------------------------
  -- Calculate component of velocity in the direction of (dx,dy)
  -- -----------------------------------------------------------
 
  local vp1 = firstBallRef.horizontalVelocity * cs + firstBallRef.verticalVelocity * sc
  local vp2 = secondBallRef.horizontalVelocity * cs + secondBallRef.verticalVelocity * sc
 
 
 
  local dt = (D + D - dxy) / (vp1 - vp2)
 
 
 
  firstBallRef.tempX = firstBallRef.tempX - (firstBallRef.horizontalVelocity * dt)
  firstBallRef.tempY = firstBallRef.tempY - (firstBallRef.verticalVelocity * dt)
 
 
 
 
  secondBallRef.tempX = secondBallRef.tempX - (secondBallRef.horizontalVelocity * dt)
  secondBallRef.tempY = secondBallRef.tempY - (secondBallRef.verticalVelocity * dt)
 
 
 
  dx = secondBallRef.tempX - firstBallRef.tempX -- horizontal distance between the 2 balls
  dy = secondBallRef.tempY - firstBallRef.tempY -- vertical distance between the 2 balls
 
  local distance = mSqrt(dx * dx + dy * dy)
  local ax = dx/distance
  local ay = dy/distance
 
 
 
  local va1 = (firstBallRef.horizontalVelocity * ax + firstBallRef.verticalVelocity * ay)
  local vb1 = (-1 * firstBallRef.horizontalVelocity * ay + firstBallRef.verticalVelocity * ax)
 
  local va2 = (secondBallRef.horizontalVelocity * ax + secondBallRef.verticalVelocity * ay)
  local vb2 = (-1 * secondBallRef.horizontalVelocity * ay + secondBallRef.verticalVelocity * ax)
 
 
 
  local vaP1 = va1 + (1 + 1) * (va2 - va1)/(1 + 1/1)
  local vaP2 = va2 + (1 + 1) * (va1 - va2)/(1 + 1/1)
 
 
  firstBallRef.horizontalVelocity = vaP1 * ax - vb1 * ay
  firstBallRef.verticalVelocity = vaP1 * ay + vb1 * ax
 
 
  secondBallRef.horizontalVelocity = vaP2 * ax - vb2 * ay
  secondBallRef.verticalVelocity = vaP2 * ay + vb2 * ax
 
 
 
  firstBallRef.tempX = firstBallRef.tempX + firstBallRef.horizontalVelocity * dt
  firstBallRef.tempY = firstBallRef.tempY + firstBallRef.verticalVelocity * dt
 
  secondBallRef.tempX = secondBallRef.tempX + secondBallRef.horizontalVelocity * dt
  secondBallRef.tempY = secondBallRef.tempY + secondBallRef.verticalVelocity * dt

 
  end
 
end




You have the following code
Code:
dt = (r1+r2-d)/(vp1-vp2);
What if vp1==vp2???


You also have the following code

Code:
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;

What if d==0???

It could also be other kind of bug in your code. You need to trace the code (find out value for variables) and try to find out the problem.
It is not easy to find the bug.  Good luck!

@prof, i've found the bug , it's on collision.
@mediakitchen i have multiple balls , how do you compare each array without having compare the same one.
for example Array 1 (ball1,ball2,ball3), Array 2 (ball1,ball2,ball3) how do you skip the same last one?
Logged
Fu-Kwun Hwang
Administrator
Hero Member
*****
Offline Offline

Posts: 3056



WWW
«
Embed this message
Reply #153 on: October 09, 2010, 10:31:14 am » posted from:,,Taiwan

Make a double loop
i=0 to n
j=i+1 to n

Logged
lunayo
Newbie
*
Offline Offline

Posts: 6


«
Embed this message
Reply #154 on: October 09, 2010, 01:13:07 pm » posted from:Jakarta,Jakarta Raya,Indonesia

Make a double loop
i=0 to n
j=i+1 to n



Thank you professor, I made it!!  Cheesy. You are a very good teacher.  Grin
Logged
mediakitchen
Newbie
*
Offline Offline

Posts: 9


«
Embed this message
Reply #155 on: October 09, 2010, 02:00:49 pm » posted from:Wantage,Oxfordshire,United Kingdom

Thank you for the reply. I should have included my code that shows where I call the collision function.

I loop through all balls and check each against all the others whilst ensuring that I do not compare the same one with itself

Code:

for (var i = 0; i < howManyBalls; i++) {

  ball1 = ballObjects[i]

 
  for (var j = 0; i < howManyBalls; j++) {

  ball2 = ballObjects[j]

  if (ball1 != ball2) {
 
  checkForCollisionWithBall(ball1, ball2 )
  }

  }



}



Is this equivalent to the double loop?


Quote
You have the following code
Code:

dt = (r1+r2-d)/(vp1-vp2);

What if vp1==vp2???


You also have the following code

Code:

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;


What if d==0???

It could also be other kind of bug in your code. You need to trace the code (find out value for variables) and try to find out the problem.
It is not easy to find the bug.  Good luck!


How do I deal with the situation where vp1 = vp2 or d = 0?

Thank you

Paul
Logged
Fu-Kwun Hwang
Administrator
Hero Member
*****
Offline Offline

Posts: 3056



WWW
«
Embed this message
Reply #156 on: October 09, 2010, 02:54:03 pm » posted from:,,Taiwan

The problem is due to your double loops.

For example: when i=0, j=0 it is not collision between two different balls.
Think about what you were doing and you will understand why it is not working.

You should change the second loop to
Code:
for (var j = i; i < howManyBalls; j++)
Logged
mediakitchen
Newbie
*
Offline Offline

Posts: 9


«
Embed this message
Reply #157 on: October 09, 2010, 03:02:19 pm » posted from:Wantage,Oxfordshire,United Kingdom

Thank you for the fast reply.

Surely my line of code that says if (ball1 != ball2) will prevent checking one ball against itself? There was a small typo in my code I typed in


Code:

for (var j = 0; i < howManyBalls; j++) {


Should have been

Code:

for (var j = 0; j < howManyBalls; j++) {


Code:


for (var i = 0; i < howManyBalls; i++) {

  ball1 = ballObjects[i]

 
  for (var j = 0; j < howManyBalls; j++) {

  ball2 = ballObjects[j]

  if (ball1 != ball2) {
 
  checkForCollisionWithBall(ball1, ball2 )
  }

  }



If I use the following:

Code:
for (var j = i; i < howManyBalls; j++)

Surely if i = 2 then j will never have a value of 0 or 1?

Thank you

Paul
Logged
mediakitchen
Newbie
*
Offline Offline

Posts: 9


«
Embed this message
Reply #158 on: October 09, 2010, 04:04:48 pm » posted from:London,London, City of,United Kingdom

With multiple balls and when looping through all balls checking for collision. If 2 balls collide we use dt to reposition them at point of collision. Do we also need to reposition all other balls to their position based on dt? Just wondered if this was possible cause of problem?

Though perhaps my double loop is still not right?

Thank you so much for help

Paul
Logged
Fu-Kwun Hwang
Administrator
Hero Member
*****
Offline Offline

Posts: 3056



WWW
«
Embed this message
Reply #159 on: October 09, 2010, 05:34:28 pm » posted from:,,Taiwan

There is another problem even you rule out case for  i==j
 
Try to set howManyBalls to 3 and following the loop.
Write down what you were asking the computer to do.
And you will find out what is the problem.

After you figure out the problem, then check out my previous suggestion for the double loop.

You need to figure out by yourself!

Code:
Surely if i = 2 then j will never have a value of 0 or 1?

The collision between 0-1 and 0-2 should have been processed when outer loop i=0, right? Cheesy
Logged
mediakitchen
Newbie
*
Offline Offline

Posts: 9


«
Embed this message
Reply #160 on: October 09, 2010, 05:54:45 pm » posted from:Wantage,Oxfordshire,United Kingdom

Thank so very much. I will try what you suggested and hope I find the problem.
Logged
mediakitchen
Newbie
*
Offline Offline

Posts: 9


«
Embed this message
Reply #161 on: October 10, 2010, 04:19:18 am » posted from:Wantage,Oxfordshire,United Kingdom

I have spent the day trying to figure this out with no joy.

I have created two test movies using Flash, one with 3 balls and one with 5, the links are as follows:

http://www.mediakitchen.co.uk/physics/testFile3balls.html
http://www.mediakitchen.co.uk/physics/testFile5balls.html

Simply click on the ball at the bottom and drag mouse to launch the ball towards the other balls. If you pull it back as much as possible before releasing mouse it will propell the ball faster. It is when it goes faster the problem occurs, especially when you aim towards the middle of the group of upper balls. It is random when it doesn't work so please try a few times.

Ok I thought I  found the problem and changed my loop to a double loop. I could really do with help fixing this problem.

Thanks

Paul

Code:

function initialiseGameConstants() {

objGame.friction = 0.8;

objGame.dV = 0.08;

objGame.D = 14; // Ball radius
objGame.D2 = (2 * objGame.D) * (2 * objGame.D)


}

function moveBallObjects(e:Event):void {


var howManyBallObjects:Number = objGame.ballObjects.length;

for (var i:Number = 0; i < howManyBallObjects; i++) {

var ballObject = objGame.ballObjects[i];

var V = (ballObject.horizontalVelocity * ballObject.horizontalVelocity) + (ballObject.verticalVelocity * ballObject.verticalVelocity);

  if (V == 0) {
 
  continue;
  }

  V = Math.sqrt(V);


  var k = (V - objGame.dV) / V;


  if (k < 0)
  {
  k = 0;
  } // end if

  ballObject.horizontalVelocity = ballObject.horizontalVelocity * k;
  ballObject.verticalVelocity = ballObject.verticalVelocity * k;

ballObject.tempX = ballObject.tempX + ballObject.horizontalVelocity;
ballObject.tempY = ballObject.tempY + ballObject.verticalVelocity;

objGame.numTotalBalls = 3;

for (var j:Number = 0; j < objGame.numTotalBalls; j++) {

var firstBallObject = objGame.ballObjects[j];

for (var f:Number = (j + 1); f < objGame.numTotalBalls; f++) {

var otherBallMC = objGame.ballObjects[f];

checkForCollisionWithBall(firstBallObject, otherBallMC);

}

}

// ---------------------------------
// Update Position of Ball On Screen
// ---------------------------------


ballObject.x = ballObject.tempX;
ballObject.y = ballObject.tempY;

}


}






function checkForCollisionWithBall(firstBallRef:MovieClip, secondBallRef:MovieClip):void {
 
  var dx = secondBallRef.tempX - firstBallRef.tempX // horizontal distance between the 2 balls
  var dy = secondBallRef.tempY - firstBallRef.tempY // vertical distance between the 2 balls
 
 
  var dxy = (dx * dx) + (dy * dy)
 
  if (dxy < 0.00001) { 
 
  return
 
  }
 
 
  if (dxy < objGame.D2) {
 
  // --------------------
  // We have a collision!
  // --------------------
 
  // ------------------------------------------------------------------------------
  // We now perform the square root to calculate the distance between the two balls
  // ------------------------------------------------------------------------------
 
  dxy = Math.sqrt(dxy)
 
  var cs = dx/dxy
  var sc = dy/dxy
 
  // -----------------------------------------------------------
  // Calculate component of velocity in the direction of (dx,dy)
  // -----------------------------------------------------------
 
  var vp1 = firstBallRef.horizontalVelocity * cs + firstBallRef.verticalVelocity * sc
  var vp2 = secondBallRef.horizontalVelocity * cs + secondBallRef.verticalVelocity * sc

  var dt = (objGame.D + objGame.D - dxy) / (vp1 - vp2)

  firstBallRef.tempX = firstBallRef.tempX - (firstBallRef.horizontalVelocity * dt)
  firstBallRef.tempY = firstBallRef.tempY - (firstBallRef.verticalVelocity * dt)

  secondBallRef.tempX = secondBallRef.tempX - (secondBallRef.horizontalVelocity * dt)
  secondBallRef.tempY = secondBallRef.tempY - (secondBallRef.verticalVelocity * dt) 
 
  dx = secondBallRef.tempX - firstBallRef.tempX // horizontal distance between the 2 balls
  dy = secondBallRef.tempY - firstBallRef.tempY // vertical distance between the 2 balls
 
  var distance = Math.sqrt(dx * dx + dy * dy)
  var ax = dx/distance
  var ay = dy/distance
 
 
 
  var va1 = (firstBallRef.horizontalVelocity * ax + firstBallRef.verticalVelocity * ay)
  var vb1 = (-1 * firstBallRef.horizontalVelocity * ay + firstBallRef.verticalVelocity * ax)
 
  var va2 = (secondBallRef.horizontalVelocity * ax + secondBallRef.verticalVelocity * ay)
  var vb2 = (-1 * secondBallRef.horizontalVelocity * ay + secondBallRef.verticalVelocity * ax)
 
 
 
  var vaP1 = va1 + (1 + 1) * (va2 - va1)/(1 + 1/1)
  var vaP2 = va2 + (1 + 1) * (va1 - va2)/(1 + 1/1)
 
 
  firstBallRef.horizontalVelocity = vaP1 * ax - vb1 * ay
  firstBallRef.verticalVelocity = vaP1 * ay + vb1 * ax
 
 
  secondBallRef.horizontalVelocity = vaP2 * ax - vb2 * ay
  secondBallRef.verticalVelocity = vaP2 * ay + vb2 * ax
 
 
 
  firstBallRef.tempX = firstBallRef.tempX + firstBallRef.horizontalVelocity * dt
  firstBallRef.tempY = firstBallRef.tempY + firstBallRef.verticalVelocity * dt
 
  secondBallRef.tempX = secondBallRef.tempX + secondBallRef.horizontalVelocity * dt
  secondBallRef.tempY = secondBallRef.tempY + secondBallRef.verticalVelocity * dt

 
  }
 
}



Logged
mediakitchen
Newbie
*
Offline Offline

Posts: 9


«
Embed this message
Reply #162 on: October 10, 2010, 04:36:07 am » posted from:Wantage,Oxfordshire,United Kingdom

Further to my last post, I have printed some variable values to the screen when the problem occurs as follows:

Code:

dxy = 11.183594089759662
cs = -0.9113209567523853
sc = -0.41169662833683374
vp1 = 10.423261322708719
vp2 = 0
dt = 1.6133535742410243
firstBallRef.tempX = 150.00761013707466
firstBallRef.tempY = 179.69153092093967
secondBallRef.tempX = 120.18423352873543
secondBallRef.tempY= 104.91271705850214
firstBallRef.horizontalVelocity = 5.118247803194922
firstBallRef.verticalVelocity = -1.4318442742343485
secondBallRef.horizontalVelocity = -6.0840764405175305
secondBallRef.verticalVelocity = -21.748043021508227
dxy = 20.415665302423797
cs = 0.9706157589148952
sc = -0.24063467860236176
vp1 = -0.6719671288981877
vp2 = 0
dt = -11.286764443391895
firstBallRef.tempX = 32.46887484970526
firstBallRef.tempY = -133.54646421285148
secondBallRef.tempX = 227.71535867903015
secondBallRef.tempY= 338.4591812713536
firstBallRef.horizontalVelocity = 1.6874473756267157
firstBallRef.verticalVelocity = -0.6207144175197532
secondBallRef.horizontalVelocity = -7.771523816144245
secondBallRef.verticalVelocity = -21.12732860398847
dxy = 21.703543611196096
cs = -0.23089377668368133
sc = 0.9729789637442047
vp1 = -2.342372578705536
vp2 = -18.295318544168257
dt = 0.3946892569206588
firstBallRef.tempX = 179.14739832875304
firstBallRef.tempY = 163.96685005743075
secondBallRef.tempX = 174.03981574604762
secondBallRef.tempY= 200.25638673254542
firstBallRef.horizontalVelocity = 4.778078082260453
firstBallRef.verticalVelocity = -20.52327562601023
secondBallRef.horizontalVelocity = -7.70027935503791
secondBallRef.verticalVelocity = -1.3810100832728573
dxy = 14.346250582823185
cs = -0.9694056603163411
sc = -0.24546418424413502
vp1 = 0.4042924324869883
vp2 = 0
dt = 33.77196385593056
firstBallRef.tempX = 37.17943584519696
firstBallRef.tempY = 836.9689122027011
secondBallRef.tempX = 316.72790067410847
secondBallRef.tempY= -553.4474215064265
firstBallRef.horizontalVelocity = 0.4152722629195494
firstBallRef.verticalVelocity = 0.08786827300331551
secondBallRef.horizontalVelocity = 4.344665927632815
secondBallRef.verticalVelocity = -20.53322763415942


I notice the value of dt is very high e.g dt = 33.77196385593056

Should dt have such a high value and if not, any idea why it is having this value?

Thank you

Paul
« Last Edit: October 10, 2010, 04:39:00 am by mediakitchen » Logged
Fu-Kwun Hwang
Administrator
Hero Member
*****
Offline Offline

Posts: 3056



WWW
«
Embed this message
Reply #163 on: October 10, 2010, 09:04:32 am » posted from:,,Taiwan

As I have said several time, there is an assumption for the code I presented (to process the collision).
It require : the time step is smaller enough so that the movement of each ball should be smaller than radius of both balls.
i.e. v*dt<< r

Code:
ballObject.tempX = ballObject.tempX + ballObject.horizontalVelocity;
Your time step is always 1.
You should change the time step to a small value when velocity is too large.

Or you should make another loop to make the ball move with smaller steps.
i.e. ballObject.tempX = ballObject.tempX + ballObject.horizontalVelocity*dt;
with proper dt value.


Another issue is you are processing collision before all the particles are moving to the next time step.
You have loop i to move particle , inside loop i
 you have loop j and loop f to process collision,

I would suggest you move loop j and loop f outside loop i.
Process collision after all particles have move one time step.

And for loop j and loop f: you are still have both loop from 0-numTotalBalls.
 It seems that you did not listen to my suggestion. The code was processing collision twice.
for example: if you have three particles  j loop from 0-2, f:loop from 0-2
  your code is doing the following (j,f) pairs
  (0,0): self collision --- not real 
  (0,1):collision between particle 0 and particle 1
  (0,2):collision between particle 0 and particle 2
  (1,0):collision between particle 1 and particle 0--- this should have been take care in (0,1)
  (1,1):self collision --- not real 
  (1,2):collision between particle 2 and particle 0--- this should have been take care in (0,2)
  (2,0):collision between particle 2 and particle 1--- this should have been take care in (1,2)
  (2,1):collision between particle 2 and particle 2
  (2,2); self collision --- not real 

You should spend some time try to draw a conceptual flow to understand what you were really doing.
Logged
mediakitchen
Newbie
*
Offline Offline

Posts: 9


«
Embed this message
Reply #164 on: October 10, 2010, 12:17:42 pm » posted from:Wantage,Oxfordshire,United Kingdom

Thanks you for your patience.

I assure you I am reading your replies and attempting to act on your advice.

With regards the time, my movie is running at 30FPS therefore I was under the impression that the largest time slot was 1/30 seconds. I assume that the "actionLoop" function (see below) is being called 30 times per second.  Please can you explain this.

I thought my loop was correct as when I traced which balls it was comparing it had the following:

Code:

firstBallRef = ball1
secondBallRef = ball2
firstBallRef = ball1
secondBallRef = ball3
firstBallRef = ball1
secondBallRef = ball4
firstBallRef = ball1
secondBallRef = ball5
firstBallRef = ball2
secondBallRef = ball3
firstBallRef = ball2
secondBallRef = ball4
firstBallRef = ball2
secondBallRef = ball5
firstBallRef = ball3
secondBallRef = ball4
firstBallRef = ball3
secondBallRef = ball5
firstBallRef = ball4
secondBallRef = ball5


I have moved my code to do the collision detection after the code to calculate all the ball object new positions based on your recommendation:

Quote
Another issue is you are processing collision before all the particles are moving to the next time step.

Code:
function actionLoop(e:Event):void {

calculateBallObjectNewPositions()
checkForCollisions()
updateBallPositions()

}

Unfortunately I am still getting the same error (New version here http://www.mediakitchen.co.uk/physics/testFile5v2balls.html ) but assume this must be due to the dt problem as the following is an example of my variable values when the issue occurs.

Code:
firstBallRef.tempX = 164.12788355997395
firstBallRef.tempY = 172.2370476331055
secondBallRef.tempX = 115.87211644002605
secondBallRef.tempY= 112.1629523668944
firstBallRef.horizontalVelocity = 9.36283073039942
firstBallRef.verticalVelocity = -4.751832309742385
secondBallRef.horizontalVelocity = -9.36283073039942
secondBallRef.verticalVelocity = -18.44816769025763
firstBallRef = ball1
secondBallRef = ball3
firstBallRef = ball1
secondBallRef = ball4
firstBallRef = ball1
secondBallRef = ball5
firstBallRef = ball2
secondBallRef = ball3
firstBallRef = ball2
secondBallRef = ball4
dxy = 27.020217899991174
cs = 0.8929566611667419
sc = -0.4501426454780135
vp1 = -0.056295059772248024
vp2 = 0
dt = -17.404406425230103
firstBallRef.tempX = -70.12509047107508
firstBallRef.tempY = -194.96160633456583
secondBallRef.tempX = 325.9972069111011
secondBallRef.tempY= 407.12455870146016
firstBallRef.horizontalVelocity = 1.3239575671590866
firstBallRef.verticalVelocity = -0.8017997994089945
secondBallRef.horizontalVelocity = -10.686788297558504
secondBallRef.verticalVelocity = -17.646367890848634


Note that the position of secondBallRef jumps from being x = 115 to x = 407, a very large movement and hence the issue I am experiencing.

Here is my updated code:

Code:
function actionLoop(e:Event):void {

calculateBallObjectNewPositions()
checkForCollisions()
updateBallPositions()

}





function calculateBallObjectNewPositions():void {


var howManyBallObjects:Number = objGame.ballObjects.length;

for (var i:Number = 0; i < howManyBallObjects; i++) {

var ballObject = objGame.ballObjects[i];

if (ballObject.alpha < 1) {



var newScale = ballObject.scaleX * 0.98;

ballObject.alpha = ballObject.alpha - 0.1;
ballObject.scaleX = newScale;
ballObject.scaleY = newScale; 

if (ballObject.alpha <= 0) {
 
  ballObject.horizontalVelocity = 0;
ballObject.verticalVelocity = 0;
 
  continue;

  } // end if
 

}


var V = (ballObject.horizontalVelocity * ballObject.horizontalVelocity) + (ballObject.verticalVelocity * ballObject.verticalVelocity);

  if (V == 0)
  {
  continue;
  } else {



}

  V = Math.sqrt(V);

  var k = (V - objGame.dV) / V;


  if (k < 0)
  {
  k = 0;
  } // end if

  ballObject.horizontalVelocity = ballObject.horizontalVelocity * k;
  ballObject.verticalVelocity = ballObject.verticalVelocity * k;

ballObject.tempX = ballObject.tempX + ballObject.horizontalVelocity;
ballObject.tempY = ballObject.tempY + ballObject.verticalVelocity;

}



}



function checkForCollisions():void {

objGame.numTotalBalls = 5;

for (var j:Number = 0; j < objGame.numTotalBalls; j++) {

var firstBallObject = objGame.ballObjects[j];
for (var f:Number = (j + 1); f < objGame.numTotalBalls; f++) {

var otherBallMC = objGame.ballObjects[f];

checkForCollisionWithBall(firstBallObject, otherBallMC);

}

}


}


function checkForCollisionWithBall(firstBallRef:MovieClip, secondBallRef:MovieClip):void {

trace ("firstBallRef = " + firstBallRef.instanceNameValue);
trace ("secondBallRef = " + secondBallRef.instanceNameValue);
 
  var dx = secondBallRef.tempX - firstBallRef.tempX // horizontal distance between the 2 balls
  var dy = secondBallRef.tempY - firstBallRef.tempY // vertical distance between the 2 balls
 
 
  var dxy = (dx * dx) + (dy * dy)
 
  if (dxy < 0.00001) { 
 
  return
 
  }
 
 
 
  if (dxy < objGame.D2) {
 
  // --------------------
  // We have a collision!
  // --------------------
 
  // ------------------------------------------------------------------------------
  // We now perform the square root to calculate the distance between the two balls
  // ------------------------------------------------------------------------------
 
  dxy = Math.sqrt(dxy)
 
  var cs = dx/dxy
  var sc = dy/dxy

trace ("dxy = " + dxy);

trace ("cs = " + cs);
trace ("sc = " + sc);
 
  // -----------------------------------------------------------
  // Calculate component of velocity in the direction of (dx,dy)
  // -----------------------------------------------------------
 
  var vp1 = firstBallRef.horizontalVelocity * cs + firstBallRef.verticalVelocity * sc
  var vp2 = secondBallRef.horizontalVelocity * cs + secondBallRef.verticalVelocity * sc
 
  trace ("vp1 = " + vp1);
trace ("vp2 = " + vp2);
 
  var dt = (objGame.D + objGame.D - dxy) / (vp1 - vp2)
 
 
 
  firstBallRef.tempX = firstBallRef.tempX - (firstBallRef.horizontalVelocity * dt)
  firstBallRef.tempY = firstBallRef.tempY - (firstBallRef.verticalVelocity * dt)
 
 
 
 
  secondBallRef.tempX = secondBallRef.tempX - (secondBallRef.horizontalVelocity * dt)
  secondBallRef.tempY = secondBallRef.tempY - (secondBallRef.verticalVelocity * dt)
 
 
 
  dx = secondBallRef.tempX - firstBallRef.tempX // horizontal distance between the 2 balls
  dy = secondBallRef.tempY - firstBallRef.tempY // vertical distance between the 2 balls
 
  var distance = Math.sqrt(dx * dx + dy * dy)
  var ax = dx/distance
  var ay = dy/distance
 
 
 
  var va1 = (firstBallRef.horizontalVelocity * ax + firstBallRef.verticalVelocity * ay)
  var vb1 = (-1 * firstBallRef.horizontalVelocity * ay + firstBallRef.verticalVelocity * ax)
 
  var va2 = (secondBallRef.horizontalVelocity * ax + secondBallRef.verticalVelocity * ay)
  var vb2 = (-1 * secondBallRef.horizontalVelocity * ay + secondBallRef.verticalVelocity * ax)
 
 
 
  var vaP1 = va1 + (1 + 1) * (va2 - va1)/(1 + 1/1)
  var vaP2 = va2 + (1 + 1) * (va1 - va2)/(1 + 1/1)
 
 
  firstBallRef.horizontalVelocity = vaP1 * ax - vb1 * ay
  firstBallRef.verticalVelocity = vaP1 * ay + vb1 * ax
 
 
  secondBallRef.horizontalVelocity = vaP2 * ax - vb2 * ay
  secondBallRef.verticalVelocity = vaP2 * ay + vb2 * ax
 
 
 
  firstBallRef.tempX = firstBallRef.tempX + firstBallRef.horizontalVelocity * dt
  firstBallRef.tempY = firstBallRef.tempY + firstBallRef.verticalVelocity * dt
 
  secondBallRef.tempX = secondBallRef.tempX + secondBallRef.horizontalVelocity * dt
  secondBallRef.tempY = secondBallRef.tempY + secondBallRef.verticalVelocity * dt

trace ("dt = " + dt);

trace ("firstBallRef.tempX = " + firstBallRef.tempX);
trace ("firstBallRef.tempY = " + firstBallRef.tempY);

trace ("secondBallRef.tempX = " + secondBallRef.tempX);
trace ("secondBallRef.tempY= " + secondBallRef.tempY);

trace ("firstBallRef.horizontalVelocity = " + firstBallRef.horizontalVelocity);
trace ("firstBallRef.verticalVelocity = " + firstBallRef.verticalVelocity);

trace ("secondBallRef.horizontalVelocity = " + secondBallRef.horizontalVelocity);
trace ("secondBallRef.verticalVelocity = " + secondBallRef.verticalVelocity);

 
  }
 
}


function updateBallPositions() {

var howManyBallObjects:Number = objGame.ballObjects.length;

for (var i:Number = 0; i < howManyBallObjects; i++) {

var ballObject = objGame.ballObjects[i];

ballObject.x = ballObject.tempX;
ballObject.y = ballObject.tempY;
}



}





It is so frustrating that this works 90% of the time.

Many thanks for your help

Paul
Logged
Fu-Kwun Hwang
Administrator
Hero Member
*****
Offline Offline

Posts: 3056



WWW
«
Embed this message
Reply #165 on: October 10, 2010, 04:26:43 pm » posted from:,,Taiwan

You should have noticed that the velocity of those two balls are not small when the problem occurs.
Your time step is 1, however, dt=-17.4 so it is the problem. The time step 1 is too large.

I know that you are under a fix time step. 30FPS or whatever time step by your program.

You are doing one step of particle movement for each frame.
Here is my suggestion for your code
Code:
function actionLoop(e:Event):void {

calculateBallObjectNewPositions()
checkForCollisions()
updateBallPositions()

}

Your time step is 1 for the above 3 functions. Please change it to smaller value. e.g. change it to 0.1

You can change code like
Code:
ballObject.tempX = ballObject.tempX + ballObject.horizontalVelocity;
ballObject.tempY = ballObject.tempY + ballObject.verticalVelocity;
to
Code:
ballObject.tempX = ballObject.tempX + ballObject.horizontalVelocity*deltat;
ballObject.tempY = ballObject.tempY + ballObject.verticalVelocity*deltat;
and define deltat=0.1 (Because we change to smaller time step 0.1 so we need to calculate it 10 times)

then, change actionLoop
Code:
function actionLoop(e:Event):void {
 for (var i:Number = 0; i < 10; i++) {
calculateBallObjectNewPositions()
checkForCollisions()
updateBallPositions()
 }
}

Now, you are calculating it with 300FPS, even the program only update the view with 30FPS.

You can change 'deltat' to other values and change the number of outer loop (1/deltat) accordingly.
It is also possible to add code to adjust deltat according to velocity distribution (in some case, this might make it more efficient).

May be it only take you 1 hour to write the code, but you might need to spend 10 hours to debug the code (if you did not understand what your were doing or if you make a mistake without noticed).
Logged
mediakitchen
Newbie
*
Offline Offline

Posts: 9


«
Embed this message
Reply #166 on: October 10, 2010, 04:54:57 pm » posted from:Wantage,Oxfordshire,United Kingdom

Thank you again. I have made the amends you suggested and it appears to work now.

http://www.mediakitchen.co.uk/physics/testFile5v2ballsDelta.html

Thank you for your patience.

Paul
Logged
lunayo
Newbie
*
Offline Offline

Posts: 6


«
Embed this message
Reply #167 on: November 07, 2010, 07:52:47 am »

Sir, how to calculate the momentum of ball hitting the wall? (Wall with various angle and various shape)
Logged
Fu-Kwun Hwang
Administrator
Hero Member
*****
Offline Offline

Posts: 3056



WWW
«
Embed this message
Reply #168 on: November 09, 2010, 01:46:24 pm » posted from:,,Taiwan

You can use the same equation as above, set m2>>m1

The result will be
 The component parallel to the wall will be the same
 but the normal component of the velocity will change direction (with the same magnitude).
Logged
thepreditor10
Newbie
*
Offline Offline

Posts: 2

«
Embed this message
Reply #169 on: February 01, 2012, 08:34:26 pm » posted from:MIDDLESBROUGH,ENGLAND,UNITED KINGDOM

i am finding this all a little confusing is there a simple way to explain it in layman's terms  Huh
Logged
Fu-Kwun Hwang
Administrator
Hero Member
*****
Offline Offline

Posts: 3056



WWW
«
Embed this message
Reply #170 on: February 01, 2012, 10:48:34 pm » posted from:LONDON,ENGLAND,UNITED KINGDOM

Please write down which part (where) you feel confusing!
Logged
thepreditor10
Newbie
*
Offline Offline

Posts: 2

«
Embed this message
Reply #171 on: February 02, 2012, 08:35:55 pm » posted from:MIDDLESBROUGH,ENGLAND,UNITED KINGDOM

i find physics confusing in general i am trying to create a simulation not far off the same as shown here for my university project i have the ball moving using angle and velocity by doing 


double scale_x=cos(angle);
double scale_y=sin(angle);
double v_x = (speed * scale_x);
double v_y = (speed * scale_y);

now i am looking to get the ball to bounce off the sides of the JPannel on collision also collision detection with two balls.
however i find it hard to understand how we are getting the balls to collide here and collision with the JPannel.
Logged
nsuhaili6
Newbie
*
Offline Offline

Posts: 1

«
Embed this message
Reply #172 on: May 07, 2012, 07:31:52 pm » posted from:Sekudai,Johor,Malaysia

Hi prof,
your coding is for a circle 2-d collision right?
how am i going to simulate for irregular shape of object?
i want to simulate for water molecules model of this shape but in 2d..
-*-


* Water-2D-dot-cross.png (60.42 KB, 1100x933 - viewed 97 times.)
Logged
Fu-Kwun Hwang
Administrator
Hero Member
*****
Offline Offline

Posts: 3056



WWW
«
Embed this message
Reply #173 on: May 08, 2012, 03:53:33 pm » posted from:Taipei,T'ai-pei,Taiwan

Do you mean three circles (as shown in the picture attached) as one object.

Then, you need to check collision between any two circles. And you need to re-derive the equation (with conservation of momentum and conservation of angular momentum and conservation of energy-- five equations for 2D case). It will be much more complicated than the above simulation.
Logged
Some1
Newbie
*
Offline Offline

Posts: 2

«
Embed this message
Reply #174 on: January 08, 2013, 06:45:36 am » posted from:Bucharest,Bucuresti,Romania

Hello!

I have utilised your algorithm in a personal project and now I need to write a documentation for it. One problem I am having is explaining to someone what the actual mass of the ball is measured in... I noticed you give the default value of m1=r1*r1; So the square of the ray of the circle but technically it can be anything.

My question is how much of m1 is a gram.
So:
1 gram = m1
m1 = ?

Thank you in hopes that you can answer my question and once again. I really appreciate your work. It has helped immensely.
Logged
Fu-Kwun Hwang
Administrator
Hero Member
*****
Offline Offline

Posts: 3056



WWW
«
Embed this message
Reply #175 on: January 08, 2013, 03:07:06 pm » posted from:Taipei,T'ai-pei,Taiwan

The mass used in the simulation can be 1g or 1kg or any other unit. It does not matter, the result will be the same (as long as all the particles used the same unit).

Because This is a two dimensional simulation, the mass is proportional to area (mass=density*area).
And the area of a circle is A=\pi r^2, that is why the mass is proportional to r*r in a 2D simulation.
(mass will be proportional to r^3 for a 3-D simulation.). 
Logged
bark46k
Newbie
*
Offline Offline

Posts: 1

«
Embed this message
Reply #176 on: September 26, 2013, 12:38:02 pm » posted from:,,Satellite Provider

great stuff!

Logged
Pages: 1 ... 4 5 [6]   Go Up
  Print  
Like what you dislike of those things are imortant. ...Wisdom
 
Jump to:  


Related Topics
Subject Started by Replies Views Last post
Collision 2D « 1 2 3 »
Dynamics
Fu-Kwun Hwang 64 102623 Last post April 11, 2011, 05:51:32 pm
by Fu-Kwun Hwang
Ejs open source java applet 1D collision carts Elastic and Inelastic Collision « 1 2 3 »
Collaborative Community of EJS
lookang 77 53124 Last post March 26, 2012, 04:05:27 pm
by lookang
4 car collision going through two intersections
Request for physics Simulations
Kennyg10 1 5616 Last post August 06, 2009, 11:51:32 am
by Fu-Kwun Hwang
1 D collision carts Elastic and Inelastic Collision
dynamics
ahmedelshfie 6 7595 Last post April 27, 2010, 02:16:18 am
by ahmedelshfie
Collision 2D
dynamics
ahmedelshfie 1 3326 Last post September 24, 2010, 07:22:37 pm
by ahmedelshfie
Powered by MySQL Powered by PHP Powered by SMF 1.1.13 | SMF © 2006-2011, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Page created in 0.275 seconds with 23 queries.since 2011/06/15