-
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;
}
-
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.
-
Thanks newblack for your response but i can not get your code to work
-
well i wrote it off the top of my head- i could have a sign flipped or a syntactical error- what isn't working?
-
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.
-
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.
-
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;
}
}
}
-
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|