Algorithm 球体-球体碰撞检测->;反应

Algorithm 球体-球体碰撞检测->;反应,algorithm,geometry,collision-detection,collision,Algorithm,Geometry,Collision Detection,Collision,我需要做一个算法来检测两个球体何时碰撞,以及碰撞后一瞬间的方向 比如说,想象一下,当你在台球比赛中打开桌子时,所有的球都“随机”地相互碰撞 所以,在开始自己编写代码之前,我在想,是否已经有了这方面的实现 提前谢谢 Cyas。-碰撞部分很容易。检查球体中心之间的距离是否小于其半径之和 至于反弹,您需要交换垂直于球体碰撞的总速度的速度量。(假设所有球体的质量相等,不同质量的组合会有所不同) struct Vec3{ 双x,y,z; } Vec3减(常数Vec3和v1,常数Vec3和v2){ vec3

我需要做一个算法来检测两个球体何时碰撞,以及碰撞后一瞬间的方向

比如说,想象一下,当你在台球比赛中打开桌子时,所有的球都“随机”地相互碰撞

所以,在开始自己编写代码之前,我在想,是否已经有了这方面的实现

提前谢谢


Cyas。-

碰撞部分很容易。检查球体中心之间的距离是否小于其半径之和

至于反弹,您需要交换垂直于球体碰撞的总速度的速度量。(假设所有球体的质量相等,不同质量的组合会有所不同)

struct Vec3{
双x,y,z;
}
Vec3减(常数Vec3和v1,常数Vec3和v2){
vec3r;
r、 x=v1.x-v2.x;
r、 y=v1.y-v2.y;
r、 z=v1.z-v2.z;
返回r;
}
双点积(常数向量3和v1,常数向量3和v2){
返回v1.x*v2.x+v1.y*v2.y+v1.z*v2.z;
}
Vec3刻度(常数Vec3&v,双a){
vec3r;
r、 x=v.x*a;
r、 y=v.y*a;
r、 z=v.z*a;
返回r;
}
Vec3项目编号(const Vec3&u、const Vec3&v){
vec3r;
r=标度(v,点积(u,v)/点积(v,v));
返回r;
}
整数距离平方(常数Vec3和v1,常数Vec3和v2){
Vec3δ=负(v2,v1);
返回产品(增量、增量);
}
结构球{
Vec3位置;
Vec3速度;
整数半径;
}
布尔多西特碰撞(常数球&s1,常数球&s2){
int rSquared=s1.半径+s2.半径;
rSquared*=rSquared;
返回距离平方(s1位置,s2位置)

编辑:如果您需要更高的精度,那么在发生碰撞时,您应该计算将两个碰撞球体向后移动多远,以便它们彼此刚好接触,然后触发执行碰撞功能。这将确保角度更加准确。

最困难的部分是旋转…我不在乎旋转,我只需要共线和“平面反应”。方向只是沿着连接中心的线。效果很好-但我认为有一个问题:我从10个球开始(没有重叠),其中只有一个有速度-经过一段时间和大量的反弹,他们都在移动。在时间间隔内,我将所有的速度加起来(abs(x)+abs(y))-如果我一开始的速度是8,那么它很快就会增长(这一定违反了一条守恒定律),但过了一段时间,它就停止增长,在20左右波动。。我很困惑,不确定我是否应该。。(注意:在检测到碰撞后,在调用performCollision之前,我以分钟为单位向后移动第一个球,直到它们不再重叠)尝试对每个球求和(sqrt(vx^2+vy^2))。
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;
}