When one circle is touching

Member
Posts: 131
Joined: 2010.08
Post: #1
I have implemented the sphere collision point algorithm that is in http://nehe.gamedev.net/data/lessons/les...?lesson=30 for two circles that have equal masses. I took the momentum code from post 8 in http://www.phy.ntnu.edu.tw/ntnujava/index.php?topic=4.
Code:
- (void) collision {
    float relativeX = (ball.ballX + ball.ballSpeedX*deltaTime) - (ball2.ballX + ball2.ballSpeedX*deltaTime);
    float relativeY = (ball.ballY + ball.ballSpeedY*deltaTime) - (ball2.ballY + ball2.ballSpeedY*deltaTime);
    
    double elasticity = 1;

    int step = 200;
    if (sqrt(pow(relativeX, 2) + pow(relativeY, 2)) <= 2*RADIUS_FRACTION){
        
        for (int i = 0; i < step; i++) {
            
            if (sqrt(pow(relativeX*(i/step), 2) + pow(relativeY*(i/step), 2)) <= 2*RADIUS_FRACTION) {
                
                ball.ballX += ball.ballSpeedX*deltaTime*((i-1)/step);
                ball.ballY += ball.ballSpeedY*deltaTime*((i-1)/step);
                ball2.ballY += ball2.ballSpeedX*deltaTime*((i-1)/step);
                ball2.ballX += ball2.ballSpeedY*deltaTime*((i-1)/step);
            }
        }
        double dx = ball.ballX-ball2.ballX, dy = ball.ballY-ball2.ballY;

        double distance = sqrt(dx*dx+dy*dy);

        double ax=dx/distance, ay=dy/distance;
    
        double va1=(ball.ballSpeedX*ax+ball.ballSpeedY*ay), vb1=(-ball.ballSpeedX*ay+ball.ballSpeedY*ax);
        double va2=(ball2.ballSpeedX*ax+ball2.ballSpeedY*ay), vb2=(-ball2.ballSpeedX*ay+ball2.ballSpeedY*ax);
    
        double vaP1=va1 + (1+elasticity)*(va2-va1)/2;
        double vaP2=va2 + (1+elasticity)*(va1-va2)/2;
    
        ball.ballSpeedX=vaP1*ax-vb1*ay;  ball.ballSpeedY=vaP1*ay+vb1*ax;
        ball2.ballSpeedX=vaP2*ax-vb2*ay;  ball2.ballSpeedY=vaP2*ay+vb2*ax;
    
}
    }
This works well except that when one circle is touching both walls of a corner and its velocity is 0, and the other circle is pushing against this circle (after coming to rest on it after several bounces), it slowly sinks into it and becomes attached to it. How to correct this problem?
Quote this message in a reply
Moderator
Posts: 3,572
Joined: 2003.06
Post: #2
Sounds like floating point error, which is a classic physics simulation problem. Too hard to explain in a forum post, but if that's the problem then you basically wind up adding a constant but small amount of opposite force (friction/drag/etc) to stabilize the integration against the floating point error.

[Adding] There are lots of good books on this topic, which are probably better to work with than stitching online tutorials together. Or you might use a third-party physics library like chipmunk to do the deed for you.
Quote this message in a reply
Member
Posts: 131
Joined: 2010.08
Post: #3
A tutorial would be nicer, as I could not find any books about floating-point errors. I found some books about computational physics which might have this topic, but it is not nice to buy a book just to correct this small problem (the game is working well otherwise).
Quote this message in a reply
Moderator
Posts: 916
Joined: 2002.10
Post: #4
Quote:I could not find any books about floating-point errors
This is where it helps to have a basic fundamental knowledge of computer science. If you want to understand why floating point numbers are not 100% precise in all cases, I suggest reading http://en.wikipedia.org/wiki/Floating_point for at least a basic understanding
Quote this message in a reply
Member
Posts: 131
Joined: 2010.08
Post: #5
I understand.
Quote:In base-2 only rationals with denominators that are powers of 2 (such as 1/2 or 3/16) are terminating. Any rational with a denominator that has a prime factor other than 2 will have an infinite binary expansion. This means that numbers which appear to be short and exact when written in decimal format may need to be approximated when converted to binary floating-point.
However, the variables have such high magnitude in my game that floating-point errors do not have an effect on it. I think that the problem is that when one circle is next to a wall and the other collides with it, it gains the other's momentum and penetrates the wall, so that its position gets updated as 2*penetration. Its new position is partly inside the other circle, as this has stayed at the collision point. Could you point to a tutorial about proper collision detection so that I could solve this problem, or is the best thing to read Game Physics Engine Development, Game Physics or Real-Time Collision Detection? (which is best?)
Quote this message in a reply
Moderator
Posts: 3,572
Joined: 2003.06
Post: #6
I've read Game Physics Engine Development. It's for 3D, although you'll find a lot of the information applicable to 2D. I don't know if I'd recommend it for what you're trying to do, but I can say it's a pretty good book. The projects are in C++ but it's one of those rare occasions where the author does a decent job of keeping the code fairly clean and straight-foward and relatively portable. I haven't read the other ones.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Ball Bouncing in a circle strikerjax 6 5,016 Jul 6, 2009 02:39 PM
Last Post: strikerjax
  2D reflecting a point off a circle Joseph Duchesne 1 2,925 Oct 23, 2004 08:05 PM
Last Post: MattDiamond