Algorithm for Direction Change upon Collision

Jim Hurley jhurley0305 at sbcglobal.net
Sat Nov 9 01:15:28 CET 2013


Hi Ender,

Your hockey puck game is *identical* to the game of pool, except you don't have to worry about the pockets.

If you want the collisions to be realistic you have to do the phyisics. Simply "swapping the directions" does not accomplish a real collission. 

For example imagine to balls/pucks moving horizontally toward each other along the same horizontal line. In that instance, swapping direction is fine. But suppose the line of A is slightly above the line of B. In this case the balls/pucks will move off at different angles, depending on the lines of separation.  You can't just swap the directions.

But this function below takes care of the physics where the xx,yy,xx',yy' and the coordinates of the two pucks before collision, and ,vxx,vyy,vxx',vyy''' are the respective velocity before the collision. The function returns the new velocities after the collision--the coordinates don't change during the moment of impact. 

function newVel  xx,yy,xx',yy',vxx,vyy,vxx',vyy'
   --This assumes an ideal elastic collision.
   --where each ball exerts a force on the other ball
   --along the line joining the centers.
   --They exchange momentum (velocity component) along this line
   --The momentum (velocity) component perpendicular to this line 
   --is unchange by the collision.
  put xx,yy into ptMe
  put xx',yy' into ptOther
  put theLineAngle(ptMe,ptOther) into tCentersAngle
  put tCentersAngle into tCa
  put xx,yy,xx+vxx,yy+vyy into tVelVector
  put theLineAngle(tVelVector) into tVa
  put sqrt(vxx'*vxx'+vyy'*vyy') into v'
  put sqrt(vxx*vxx+vyy*vyy) into v
  
  put xx',yy',xx'+vxx',yy'+vyy' into tVelVector'
  put theLineAngle(tVelVector') into tVa'
  --Angle of the vVector relative to the line joining centers
  put tVa - tCa into tVrA 
  put tVa'- tCa into tVrA'
  

  put v*sin(tVrA) into vT
  put v'*cos(tVrA') into vR
  put  v'*sin(tVrA') into vT'
  
  put vR*cos(tCa) - vT*sin(tCa) into vxx
  put vR*sin(tCa) + vT*cos(tCa) into vyy
   
  put vR'*cos(tCa) - vT'*sin(tCa) into vxx'
  put vR'*sin(tCa) + vT'*cos(tCa) into vyy'
  return vxx,vyy,vxx',vyy'
end newVel

function theLineAngle p1,p2
  --Angle of line defined by the two points p1 and p2
  get the paramCount
  if it is 1 then
    put item 3 to 4 of p1 into p2
    put item 1 to 2 of p1 into p1
  end if
  put item 1 of p2 - item 1 of p1 into dx
  put item 2 of p2 - item 2 of p1 into dy
  put atan2(dy,dx) into tAngle
  return tAngle
end theLineAngle

I know it's a mess, but so is the physics. 

And as for collision detection, that happens when the distance between the centers of any two balls/pucks is less than the diameter of the balls/pucks.

Jim




> 
> Message: 15
> Date: Fri, 8 Nov 2013 23:07:58 +0200
> From: Ender Nafi Elekcioglu <endernafi at gmail.com>
> To: How to use LiveCode <use-livecode at lists.runrev.com>
> Subject: Re: Algorithm for Direction Change upon Collision
> Message-ID: <etPan.527d52ae.238e1f29.160 at fdbqMacBookPro.local>
> Content-Type: text/plain; charset="utf-8"
> 
> Scott, you?re the man :)
> 
> Interestingly, my collision code was exactly same as yours?
> {I mean the intersect() section, swapping the directions and all},
> EXCEPT?
> that teeny, tiny line of *exit repeat* :))
> 
> It solved the whole thing.
> 
> I mean, almost...
> There are some little glitches but nothing which can?t be handled.
> Occasionally some pucks can escape off the screen boundaries
> and again occasionally some pucks overlap each other.
> Yet, after a while they release from themselves.
> 
> Performance is pretty good, too.
> I could go up to 32 huge pucks at a 28 fps speed.
> More than 32 pucks, refresh rate drops significantly.
> But I need just ~20 particles and they will be tiny.
> 
> I still need to improve it by implementing Jim?s, Mark?s and Bernd?s suggestions.
> There will be small sprite animations, thus I need efficiency and optimization.
> 
> 
> Anyways, thank you very much.
> 
> 
> -> one more thing:
> Do you think falling back to C++, writing some code snippets for performance driven sections, could help this kinda situations?
> Passing the locs to a dedicated C++ collision detector external and getting the result, maybe?
> Although on a second thought, the intersect() itself is written in C++, right?
> So, what are the odds that I can write more efficient / faster code than RunRev team?
> Perhaps, this last question deserves a separate thread; still I wanna hear your { plural :) } thoughts?
> 
> 
> Kindest Regards,
> 
> ~ Ender Nafi



More information about the use-livecode mailing list