我想找個當靜態和運動中的球之間碰撞的發生,但我想出了算法,有時沒有檢測到碰撞和運動球穿過靜態的。移動的球體受重力影響,靜止的球體不受重力影響。簡單的2D碰撞問題
這裏是我的碰撞檢測代碼:
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 the time when objects collide if a 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)
//
// We are interested in the 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;
}
這裏是調用碰撞檢測更新功能:
void GamePhysicsManager::updateBallPhysics()
{
//
//Update velocity
vVelocity->y -= constG/GAME_FPS; //v = a * 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 the results that are first to collide collision
vVelocity->x = ballSphere.vVelocity.x;
vVelocity->y = ballSphere.vVelocity.y;
vPosition->x = ballSphere.vPosition.x;
vPosition->y = ballSphere.vPosition.y;
}
爲什麼沒有病例的100%被檢測碰撞?僅在70%的情況下才被發現。 謝謝。
UPDATE:問題似乎解決了,當我改變從30 FPS至10如何FPS影響我的碰撞檢測?
那麼在這種情況下嘗試設置FPS很高和調試程序行由行,仔細觀察變量值如何與你認爲他們應該是一致的。 – 2010-01-15 19:14:10
您能否提供有關respondToCollision功能的更多詳細信息?特別是,檢測與第三方的進一步衝突是否有效?你如何處理一個框架中的多個碰撞? – markets 2010-01-15 19:18:15