Aggrav8d
10-16-2004, 02:25 PM
Situation: I have two circles of equal size and mass moving towards each other. They are offset such that when they collide they just barely graze each other. Arbitrary angular velocities.
Problem: They do not bounce off of each other and lose their angular velocity. They become stuck together and begin orbiting around each other, faster and faster, until they "blow apart". When that happens all collisions every cease to function - everything just flies through everything else.
Question: Why does this happen? What do i do about it? I suspect that my normal calculation is wrong, somehow.
Hacked together test case:
I am using RK2 integration with a constraint manager max_error of 0.0001 and a step size of 1/30s.
both radius=10
both mass=1
both inertia tensor=(1,1,1)
p1(-20,-10,0)
p2(20,9.078786,0) //9.078785 does not get stuck
v1(5,0,0)
v2(-5,0,0)
I wrote the following code to override DL_dyna_system_callbacks::do_collision_detection() . I hope the error is not in there but I have included it to be thorough.
int i,j;
for(i=0;i<entities.size();++i) {
DynamicPhysicsEntity *dpe=(DynamicPhysicsEntity *)entities[i];
DL_vector *v=dpe->companion->get_velocity();
// test against other objects
for(j=i+1;j<entities.size();++j) {
DynamicPhysicsEntity *dpe2=(DynamicPhysicsEntity *)entities[j];
// bbox test
float r2(dpe->radius+dpe2->radius);
float dx(dpe2->pos.x-dpe->pos.x);
if(fabs(dx)>r2)
continue;
float dy(dpe2->pos.y-dpe->pos.y);
if(fabs(dy)>r2)
continue;
// circle test
float d2(dx*dx+dy*dy);
if(d2<=r2*r2) {
// close enough together
//DL_vector*v2=dpe2->companion->get_velocity();
//if(v->inprod(v2)<0)
{
// moving into each other
float denom(dpe->radius/r2);
n.init(dx,dy,0);
float len(n.norm());
n.timesis(1.0f/len);
// (len/r2) was to try and get the point in the center of the
// overlapping area of the two circles. it can be removed and
// there will be no change.
p2.init((dx*denom)*(len/r2)+dpe->pos.x,
(dy*denom)*(len/r2)+dpe->pos.y,
0);
dpe->companion->to_local(&p2,NULL,&p0);
dpe2->companion->to_local(&p2,NULL,&p1);
// changing the 2 to a 1 will make no difference, either.
new DL_collision(dpe->companion,&p0,dpe2->companion,&p1,&n,2);
}
}
}
}
Problem: They do not bounce off of each other and lose their angular velocity. They become stuck together and begin orbiting around each other, faster and faster, until they "blow apart". When that happens all collisions every cease to function - everything just flies through everything else.
Question: Why does this happen? What do i do about it? I suspect that my normal calculation is wrong, somehow.
Hacked together test case:
I am using RK2 integration with a constraint manager max_error of 0.0001 and a step size of 1/30s.
both radius=10
both mass=1
both inertia tensor=(1,1,1)
p1(-20,-10,0)
p2(20,9.078786,0) //9.078785 does not get stuck
v1(5,0,0)
v2(-5,0,0)
I wrote the following code to override DL_dyna_system_callbacks::do_collision_detection() . I hope the error is not in there but I have included it to be thorough.
int i,j;
for(i=0;i<entities.size();++i) {
DynamicPhysicsEntity *dpe=(DynamicPhysicsEntity *)entities[i];
DL_vector *v=dpe->companion->get_velocity();
// test against other objects
for(j=i+1;j<entities.size();++j) {
DynamicPhysicsEntity *dpe2=(DynamicPhysicsEntity *)entities[j];
// bbox test
float r2(dpe->radius+dpe2->radius);
float dx(dpe2->pos.x-dpe->pos.x);
if(fabs(dx)>r2)
continue;
float dy(dpe2->pos.y-dpe->pos.y);
if(fabs(dy)>r2)
continue;
// circle test
float d2(dx*dx+dy*dy);
if(d2<=r2*r2) {
// close enough together
//DL_vector*v2=dpe2->companion->get_velocity();
//if(v->inprod(v2)<0)
{
// moving into each other
float denom(dpe->radius/r2);
n.init(dx,dy,0);
float len(n.norm());
n.timesis(1.0f/len);
// (len/r2) was to try and get the point in the center of the
// overlapping area of the two circles. it can be removed and
// there will be no change.
p2.init((dx*denom)*(len/r2)+dpe->pos.x,
(dy*denom)*(len/r2)+dpe->pos.y,
0);
dpe->companion->to_local(&p2,NULL,&p0);
dpe2->companion->to_local(&p2,NULL,&p1);
// changing the 2 to a 1 will make no difference, either.
new DL_collision(dpe->companion,&p0,dpe2->companion,&p1,&n,2);
}
}
}
}