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
Post a Comment