Я должен сделать алгоритм, который обнаруживает, когда две сферы сталкиваются, и, направление то, что каждый займет момент после коллизии.
Позвольте говорят, Воображают как то, когда Вы открываете свою таблицу в соответствии пула, все шары сталкиваются тот другому "случайным образом".
Так, прежде, чем начать писать код самостоятельно, я думал, существует ли уже реализация этого там.
Заранее спасибо!
Cyas.-
Часть столкновения проста. Убедитесь, что расстояние между центрами сфер меньше суммы их радиусов.
Что касается отскока, вам нужно поменять местами значения скорости, которые вносят вклад в общую скорость перпендикулярно столкновению сфер. (Предполагая, что все ваши сферы имеют одинаковую массу, она будет разной для комбинации разных масс)
struct Vec3 {
double x, y, z;
}
Vec3 minus(const Vec3& v1, const Vec3& v2) {
Vec3 r;
r.x = v1.x - v2.x;
r.y = v1.y - v2.y;
r.z = v1.z - v2.z;
return r;
}
double dotProduct(const Vec3& v1, const Vec3& v2) {
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
Vec3 scale(const Vec3& v, double a) {
Vec3 r;
r.x = v.x * a;
r.y = v.y * a;
r.z = v.z * a;
return r;
}
Vec3 projectUonV(const Vec3& u, const Vec3& v) {
Vec3 r;
r = scale(v, dotProduct(u, v) / dotProduct(v, v));
return r;
}
int distanceSquared(const Vec3& v1, const Vec3& v2) {
Vec3 delta = minus(v2, v1);
return dotProduct(delta, delta);
}
struct Sphere {
Vec3 position;
Vec3 velocity;
int radius;
}
bool doesItCollide(const Sphere& s1, const Sphere& s2) {
int rSquared = s1.radius + s2.radius;
rSquared *= rSquared;
return distanceSquared(s1.position, s2.position) < rSquared;
}
void performCollision(Sphere& s1, Sphere& s2) {
Vec3 nv1; // new velocity for sphere 1
Vec3 nv2; // new velocity for sphere 2
// this can probably be optimised a bit, but it basically swaps the velocity amounts
// that are perpendicular to the surface of the collistion.
// If the spheres had different masses, then u would need to scale the amounts of
// velocities exchanged inversely proportional to their masses.
nv1 = s1.velocity;
nv1 += projectUonV(s2.velocity, minus(s2.position, s1.position));
nv1 -= projectUonV(s1.velocity, minus(s1.position, s2.position));
nv2 = s2.velocity;
nv2 += projectUonV(s1.velocity, minus(s2.position, s1.position));
nv2 -= projectUonV(s2.velocity, minus(s1.position, s2.position));
s1.velocity = nv1;
s2.velocity = nv2;
}
РЕДАКТИРОВАТЬ: Если вам нужна большая точность, то при столкновении вы должны вычислить, как далеко переместить обе сталкивающиеся сферы назад, чтобы они просто коснитесь друг друга, а затем активируйте функцию выполнения столкновений. Так углы будут более точными.