C++ (Qt)bool BallsCollided( Ball & ball1, Ball & ball2 ){ QVector3D r0 = ball1.pos - ball2.pos; QVector3D u = ball1.speed - ball2.speed; float u2 = u.lengthSquared(); float r0u = QVector3D::dotProduct(r0, u); float rho2 = r0.lengthSquared() - r0u*r0u/u2; return (rho2 < 4*Ball::radius * Ball::radius);}
C++ (Qt)Ball b1, b2; // первый шарик справа и движется вправоb1.position = QVector3D(1, 0, 0):b1.speed = QVector3D(1, 0, 0): // а второй стоит в (0, 0, 0)b2.position = QVector3D(0, 0, 0):b2.speed = QVector3D(0, 0, 0): Ball::radius = 0.4f;bool collided = BallCollided(b1, b2);
C++ (Qt)bool BallsCollided( Ball & b1, Ball & b2 ){ if ((b1.position - b2.position).length() > Ball::radius * 2) // не пересеклись? return false; // пересеклись, считаем новые скорости return true;}
C++ (Qt)while (true) { BallsCollided(b1, b2); b1.position += b1.speed * dt; // часто для простоты dt = 1 b2.position += b2.speed * dt; }
C++ (Qt)bool BallsCollided( Ball & ball1, Ball & ball2 ){ QVector3D r0 = ball1.pos - ball2.pos; QVector3D u = ball1.speed - ball2.speed; float u2 = u.lengthSquared(); float r0u = QVector3D::dotProduct(r0, u); float rho2 = r0.lengthSquared() - r0u*r0u/u2; return (rho2 < 4.0*Ball::radius * Ball::radius) & (r0u < 0.0f);}
C++ (Qt)ball.position += ball.speed;
C++ (Qt)bool BallsCollded( Ball & b1, Ball & b2, float dt = 1.0f ){// находим напр-е AB QVector3D vecAB = b1.speed - b2.speed; float curSpeed = vecAB.length(); // убедимся что разница скоростей достаточно велика const double minSpeed = 1.0e-7; if (curSpeed < minSpeed) return false; vecAB /= curSpeed; // находим длину AB как проекцию AC на напр-е AB QVector3D vecAC = b1.position - b2.position; float lenAB = QVector3D::dotProduct(vecAC, vecAB); // если lenAB отрицательна, то шары расходятся if (lenAB <= 0) return false; // по теореме Пифагора находим квадрат длины катета BC float lenBC2 = vecAC.lengthSquared() - lenAB * lenAB; // если lenBC2 < квадрата (двойного) радиуса, то шарики никогда не пересекутся float R2 = Ball:radius * Ball:radius * 4; if (lenBC2 > R2) return false; // из тр-ка DBC найдем длину BD float lenBD = sqrt(R2 - lenBC2); // длина AD = время первого касания float t0 = lenAB - lenBD; // успеют ли шарики столкнуться за время dt ? if (t0 * dt > curSpeed) return false; // столкнулись, рассчитываем новые скорости ... return true;}
C++ (Qt)// длина AD = время первого касания float t0 = lenAB - lenBD; // успеют ли шарики столкнуться за время dt ? if (t0 * dt > curSpeed) return false;
C++ (Qt)// длина AD = время первого касания float lenAD = lenAB - lenBD; // успеют ли шарики столкнуться за время dt ? if ( lenAD > curSpeed * dt ) return false;