Skip to main content
GameDev.net gamedev.net
🔒 Locked

Any improvments for my Sphere Collision Algorithm

Started by Danny02 May 15, 2010 at 11:46 AM 1 replies 1.5k views
Original Post
Danny02
Danny02
Today i sat down in wrote me a function which checks if 2 moving Spheres collide or not because I need this for my Game projekt. And I wondered if there are any improvments performance wise which can be done. Ps: I tested it a bit but would be glad if any bugs can be found

public boolean checkCollision(Sphere s1, Sphere s2){
// s2 position relativ to s1
        Vec3f pos = (Vec3f) s2.getPosition().sub(s1.getPosition()); 
// s2 velocity relativ to s1
        Vec3f vel = (Vec3f) s2.getVelocity().sub(s1.getVelocity()); 

        float dot = pos.dot(vel);
        if(dot>0) // if s2 is moving away from s1 no collision
            return false;

// calculates the nearest point from s1 to the moving line of s2
// p: nearest point on the line(s2.p + x * s2.v) to s1
// lenquad gives back the length of a Vector with out pulling the squarroot
        float vellenquad = vel.lenquad(); 
        float x = (-dot)/vellenquad;
        Vec3f p = new Vec3f(); 
//the second argument of add and mul methods is where the result is saved
        pos.add(vel.mul(x, p),p);

        float distquad = p.lenquad(); // distance² from s1 to line: s2.p + x * s2.v

        float mindist = s1.getRadius() + s2.getRadius();
        float mindistquad = mindist * mindist;
        if(distquad>mindistquad)
            return false; // no collision cause the moving line of s2 is never near s1

        double fen = Math.sqrt(mindist - distquad); //pytagoras
        double vellen = Math.sqrt(vellenquad); // length of velocity vector
// x value of the collision, in the line function s2.p + x * s2.v
        double fenx = x - fen/vellen; 
        if(fenx > 1)
            return false; // on a way to collision but not this frame

        // normal vector on which the velocity vector from both sphere gets refelcted after the collision
        Vec3f normal = vel.mul((float)(-fen/vellen));
        normal.add(p, normal);
        normal.mul(s1.getRadius()/mindist, normal);
        
        // exact position where both sphers collide
        Vec3f colpos = normal.add(s1.getPosition());
        
        //percenteg of movment both sphers went before the collision, indicates how much they still have to travel(permoved * s1.vel for excample)
        double permoved = fenx / x; // percentage of the movment of both spheres until collision

        fireEvent(new CollisionEvent(s1, s2, normal, colpos, permoved));

        return true;
    }

Maesse
Maesse
If you don't actually need to detect the collision before they happen, I'd suggest simply applying the velocity, then do a simple Circle intersect.. You can always save to old position, if you want to backtrack.

Basically,
bool hasCollision = s1.Radius+s2.Radius
I doubt there's anything father than this.
Danny02
Danny02
yeah but so I get objects jumping through others and stuff.

also what to do with objects when they already stuck together^^

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.