A Flash Developer Resource Site

Results 1 to 8 of 8

Thread: coefficient of restitution ?

  1. #1
    Junior Member
    Join Date
    Sep 2007
    Location
    kent, uk
    Posts
    20

    Question coefficient of restitution ?

    Can some one please help me insert the coefficient of restitution (e) into the following code.
    The code as is stands is elastic collision only :-
    Code:
    var dx  :Number=cararray[i2].x-cararray[i1].x,
         dy  :Number=cararray[i2].y-cararray[i1].y,
         dist:Number=Math.sqrt(dx*dx+dy*dy);
    					                
    if (dist<=cardiameter) {
    
        // find the angle between the cars
        var angle:Number=Math.atan2(dy,dx),
        cosa      :Number=Math.cos(angle),
        sina       :Number=Math.sin(angle),
    
        // find the current linear momentum on each axis for each car
        // I think this rotates the coordinate system so that we can
        // determine a 2 dimensional collision
        var vx1p:Number=cosa*cararray[i1].velx+sina*cararray[i1].vely,
             vy1p:Number=cosa*cararray[i1].vely-sina*cararray[i1].velx,
             vx2p:Number=cosa*cararray[i2].velx+sina*cararray[i2].vely,
             vy2p:Number=cosa*cararray[i2].vely-sina*cararray[i2].velx;
    
        // p = momentum?
        // v = velocity?
        var p:Number=vx1p*cararray[i1].mass+vx2p*cararray[i2].mass,
             v:Number=vx1p-vx2p;
    
        vx1p=(p-cararray[i2].mass*v)/(cararray[i1].mass+cararray[i2].mass);
        vx2p=v+vx1p;
    
        // tell each car how fast they're going on each axis
        cararray[i1].velx=cosa*vx1p-sina*vy1p;
        cararray[i1].vely=cosa*vy1p+sina*vx1p;
        cararray[i2].velx=cosa*vx2p-sina*vy2p;
        cararray[i2].vely=cosa*vy2p+sina*vx2p;
    		
        // Work out the where the cars are colliding along the
        // "Line of Action" so that we can project them far enough
        // away from each other to no longer intersect
        diff=((cardiameter)-dist)/2;
        var cosd:Number=cosa*diff,
              sind:Number=sina*diff;
    
        // update their positions
        cararray[i1].x-=cosd;
        cararray[i1].y-=sind;
        cararray[i2].x+=cosd;
        cararray[i2].y+=sind;
    
    }

  2. #2
    Senior Member
    Join Date
    May 2006
    Location
    Manhattan
    Posts
    246
    you're doing way more than you need to here (with a decent amount of computational overhead), and making it difficult to solve for a non-elastic response. this might be fairly long-winded, but will give you a solution, and one that performs a lot better.

    firstly, you always want to avoid computing a square root wherever possible- you can check to see if the circles are intersecting by checking the square of the distance between them against the squared sum of their radii:
    Code:
    //i don't know what data type you're using- dynamic MovieClips?
    var car1:Object = cararray[ i1 ];
    var car2:Object = cararray[ i2 ];
    
    var diffx:Number = car1.x - car2.x;
    var diffy:Number = car1.y - car2.y;
    if( diffx * diffx + diffy * diffy <= cardiameter * cardiameter )
    {
       //circles colliding
    }
    so then you want to solve for the impulse, which is a scalar and effected by the coefficient of restitution. each object should have this defined within the bounds 0 <= e <= 1.
    Code:
    var restitution:Number = ( car1.e + car2.e ) * 0.5;
    
    //relative velocity
    var rvx:Number = car1.velx - car2.velx;
    var rvy:Number = car1.vely - car2.vely;
    
    //if their relative velocity along the collision normal is greater than or equal to zero, 
    //they are moving apart, we shouldn't try to resolve a collision n this situation as it 
    //could cause sticking, especially when close to zero
    if( rvx * diffx + rvy * diffy >= 0 ) return;
    
    //if we're this far in the algorithm, we're definitely going to apply a collision response
    //so it's fair to make a square root call- we need the normalized collision normal
    var length:Number = Math.sqrt( diffx * diffx + diffy * diffy );
    
    //diff becomes the normalized collision normal
    diffx /= length;
    diffy /= length;
    
    //you should store an inverse mass property on each car too- 1 / mass
    var invMassSum:Number = car1.invMass + car2.invMass;
    var denominator:Number = diffx * diffx * invMassSum + diffy * diffy * invMassSum;
    
    //now we can solve for the impulse
    var impulsex:Number = diffx * rvx * -( 1 + restitution );
    var impulsey:Number = diffy * rvy * -( 1 + restitution );
    
    impulsex /= denominator;
    impulsey /= denominator;
    
    //add the impulse to each circle's velocity
    car1.velx += impulsex * car1.invMass;
    car1.vely += impulsey * car1.invMass;
    
    //i just changed, this, had this as car1 by accident
    car2.velx -= impulsex * car2.invMass;
    car2.vely -= impulsey * car2.invMass;
    happy to help out if anything's unclear. this should be a lot faster as it has no trigonometric function calls and less multiplication too.
    Last edited by newblack; 12-22-2008 at 09:38 PM.

  3. #3
    Junior Member
    Join Date
    Sep 2007
    Location
    kent, uk
    Posts
    20
    Thanks newblack for your response but i can not get your code to work

  4. #4
    Senior Member
    Join Date
    May 2006
    Location
    Manhattan
    Posts
    246
    well i wrote it off the top of my head- i could have a sign flipped or a syntactical error- what isn't working?

  5. #5
    Junior Member
    Join Date
    Sep 2007
    Location
    kent, uk
    Posts
    20
    I would love to get this working, could you please check code as I'm sure your more educated than me, I'm just getting to grips with all this math, cheers m8. Ps can you give me an example as to what car.invmass value would be, sorry for me sounding stupid.

  6. #6
    Senior Member
    Join Date
    May 2006
    Location
    Manhattan
    Posts
    246
    inverse mass is just that: 1/mass. so if your car's mass is 10kg, its inverse mass is 1/10kg.

    i had both changes effecting car1's velocity (copy&paste error)- which should've resulted in no change (unless the car's mass differential is large). i edited and fixed it in my original post.

  7. #7
    Junior Member
    Join Date
    Sep 2007
    Location
    kent, uk
    Posts
    20

    Cool

    Still can not get this to work, sometimes cars(circles) bounce off each over other times they go through one another please help.

    CARTOTAL=4
    c1.e and c2.e=.5
    c1.invMass and c2.invMass = 1/1

    PHP Code:
    for (var i1:int=0;i1<CARTOTAL-1;i1++) {
      for (var 
    i2:int=i1+1;i2<CARTOTAL;i2++) {
                        
        var 
    c1:Object=carcontainer.getChildAt(i1);
        var 
    c2:Object=carcontainer.getChildAt(i2);
                                
        var 
    diffx:Number=c1.x-c2.x;
        var 
    diffy:Number=c1.y-c2.y;

        if (
    diffx*diffx+diffy*diffy<=40*40) {
                                                    
          var 
    restitution:Number=(c1.e+c2.e)*0.5;

          
    // relative velocity
          
    var rvx:Number=c1.velx-c2.velx;
          var 
    rvy:Number=c1.vely-c2.vely;
                        
          
    // if their relative velocity along the collision normal is greater than or qual to zero, 
          // they are moving apart, we shouldn't try to resolve a collision n this situation as it 
          // could cause sticking, especially when close to zero
          
    if(rvx*diffx+rvy*diffy>=0) continue;

          
    // if we're this far in the algorithm, we're definitely going to apply a collision response
          // so it's fair to make a square root call- we need the normalized collision normal
          
    var len:Number=Math.sqrt(diffx*diffx+diffy*diffy);

          
    // diff becomes the normalized collision normal
          
    diffx/=len;
          
    diffy/=len;

          
    // you should store an inverse mass property on each car too- 1 / mass
          
    var invMassSum :Number=c1.invMass+c2.invMass;
          var 
    denominator:Number=diffx*diffx*invMassSum+diffy*diffy*invMassSum;

          
    // now we can solve for the impulse
          
    var impulsex:Number=diffx*rvx*-(1+restitution);
          var 
    impulsey:Number=diffy*rvy*-(1+restitution);
                        
          
    impulsex/=denominator;
          
    impulsey/=denominator;

          
    // add the impulse to each circle's velocity
          
    c1.velx+=impulsex*c1.invMass;
          
    c1.vely+=impulsey*c1.invMass;
                
          
    c2.velx-=impulsex*c2.invMass;
          
    c2.vely-=impulsey*c2.invMass;
          }
       }


  8. #8
    Junior Member
    Join Date
    Sep 2007
    Location
    kent, uk
    Posts
    20
    any takers, please..

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center