c++ - simple 2d collision problem -


i want find when collision between static , moving ball occurs, algorithm came with, doesn't detect collision , moving ball goes through static one. moving ball affected gravity , static 1 not.

here's collision detection code:

glfloat whenspherescollide(const sphere2d &firstsphere, const sphere2d &secondsphere) {     vector2f relativeposition = subtractvectors(firstsphere.vposition, secondsphere.vposition);     vector2f relativevelocity = subtractvectors(firstsphere.vvelocity, secondsphere.vvelocity);      glfloat radiussum = firstsphere.radius + secondsphere.radius;      //we'll find time when objects collide if collision takes place      //r(t) = p[0] + t * v[0]     //     //d^2(t) = p[0]^2 + 2 * t * p[0] * v[0] + t^2 * v[0]^2     //     //d^2(t) = v[0]^2 * t^2 + 2t( p[0] . v[0] ) + p[0]^2     //     //d(t) = r     //     //d(t)^2 = r^2     //     //v[0]^2 * t^2 + 2t( p[0] . v[0] ) + p[0]^2 - r^2 = 0     //     //delta = ( p[0] . v[0] )^2 - v[0]^2 * (p[0]^2 - r^2)     //     //  interested in lowest t:     //     //t = ( -( p[0] . v[0] ) - sqrt(delta) ) / v[0]^2     //      glfloat equationdelta = squaref( dotproduct(relativeposition, relativevelocity) ) - squarev( relativevelocity ) * ( squarev( relativeposition ) - squaref(radiussum)  );      if (equationdelta >= 0.0f)     {         glfloat collisiontime = ( - dotproduct(relativeposition, relativevelocity) - sqrtf(equationdelta) ) / squarev(relativevelocity);          if (collisiontime >= 0.0f && collisiontime <= 1.0f / game_fps)         {             return collisiontime;         }     }      return -1.0f; } 

and here updating function calls collision detection:

void gamephysicsmanager::updateballphysics() {     //     //update velocity     vvelocity->y -= constg / game_fps;  //v = * t = g * 1 sec / (updates per second)      shouldapplyforcestoball = true;      vposition->x += vvelocity->x / game_fps;     vposition->y += vvelocity->y / game_fps;      if ( distancebetweenvectors( *pball->getpositionvector(), *pbasket->getpositionvector() ) <= pbasket->getradius() + vectorlength(*vvelocity) / game_fps )     {         //ball sphere         sphere2d ballsphere;         ballsphere.radius = pball->getradius();         ballsphere.mass = 1.0f;         ballsphere.vposition = *( pball->getpositionvector() );         ballsphere.vvelocity = *( pball->getvelocityvector() );           sphere2d ringsphereright;         ringsphereright.radius = 0.05f;         ringsphereright.mass = -1.0f;         ringsphereright.vposition = *( pbasket->getpositionvector() );         //ringsphereright.vposition.x += pbasket->getradius();         ringsphereright.vposition.x += (pbasket->getradius() - ringsphereright.radius);         ringsphereright.vvelocity = zerovector();           glfloat collisiontime = whenspherescollide(ballsphere, ringsphereright);          if ( collisiontime >= 0.0f )         {             debuglog("collision");             respondtocollision(&ballsphere, &ringsphereright, collisiontime, pball->getrestitution() * 0.75f );         }          //         //implement selection of results first collide collision          vvelocity->x = ballsphere.vvelocity.x;         vvelocity->y = ballsphere.vvelocity.y;          vposition->x = ballsphere.vposition.x;         vposition->y = ballsphere.vposition.y;     } 

why isn't collision being detected in 100% of cases? it's being detected in 70% of cases. thanks.

update: problem seems solved when change fps 30 10. how fps affect collision detection?

delta = ( p[0] . v[0] )^2 - v[0]^2 * (p[0]^2 - r^2) 

shouldn't delta = b2 - 4 ac?


[edit] oh see, factored 4 out. in case, sure you're considering both solutions t?

t = ( -( p[0] . v[0] ) - sqrt(delta) ) / v[0]^2 

and

t = ( -( p[0] . v[0] ) + sqrt(delta) ) / v[0]^2 

Comments

Popular posts from this blog

c++ - Convert big endian to little endian when reading from a binary file -

linq to sql - Linq2EF: Return DateTime with a TimeZone Offset -

gdi+ - WxWidgets draw a bitmap with opacity -