views:

71

answers:

2

I have created a collision class to detect collisions using pixels. In my class I've also developed some functions for determining the collsion angle. Based on this I created some examples:

http://megaswf.com/serve/25437/

http://megaswf.com/serve/25436/

(Space to change gravity, right/left to give some speed to the ball.)

As you will probably notice, there are strange things that happen:

  • When the ball speed is very low
  • When the direction of the ball is almost tangent to the obstacle.

collision

The above image shows how I calculate the collision angle. I call the red dots the keypoints. I search for a maximum number of keypoints (normally 4). If I find more then 2 keypoints, I choose the 2 farthest ones (as shown in one of the blue objects). Thats how I then find the normal angle to where in the surface the object collided. I don't know if this is an obsolete way of doing things.

based on that angle, I rotate the speed vector to do the bouncing.

The piece of code to do the maths is here:

static public function newSpeedVector(speedX: Number, speedY: Number, normalAngle: Number): Object{
            var vector_angle: Number = Math.atan2(speedY, speedX) * (180/Math.PI);
            var rotating_angle: Number = (2*(normalAngle - vector_angle) + 180) % 360;
            var cos_ang: Number = Math.cos(rotating_angle/DEGREES_OF_1RAD);
            var sin_ang: Number = Math.sin(rotating_angle/DEGREES_OF_1RAD);
            var final_speedX: Number = speedX * cos_ang - speedY * sin_ang;
            var final_speedY: Number = speedX * sin_ang + speedY * cos_ang;

            return {x_speed: final_speedX, y_speed: final_speedY};
        }

This is how the new speed vector is calculated...

My question is, has anyone faced this kind of problem or has some idea on how to avoid this from happening?

+2  A: 

Without seeing your code, this is the best I can provide.

Collision physics should have some velocity threshold that is considered "stopped". That is, once the velocity gets small enough you should explicitly mark an object as stopped and exempt it from your collision code. This will help stabilize slow moving objects. Trial and error is required for a good threshold.

When a collision happens, it is important to at least attempt to correct any inter-penetration. This is most likely the reason why tangent collisions are behaving strangely. Attempt to move the colliding object away from what it hit in a reasonable manner.

Your method of determining the normal should work fine. Game physics is all about cheating (cheating in a way that still looks good). I take it rotation and friction isn't a part of what you're going for?

Try this. You have the contact normal. When you detect a collision, calculate the penetration depth and move your object along the normal so that is isn't penetrating anymore. You can use the two points you have already calculated to get one point of penetration, you'll need to calculate the other though. For circles it's easy (center point + radius in direction of normal). There are more complex ways of going about this but see if the simple method works well for you.

I have read and recommend this book: Game Physics Engine Development

colithium
Added more information :)
joxnas
about the small speed issue, yeah, I know that I must define a minimum speed that is different from 0. But if I do that the ball penetrates the wall. So it's all a matter of keeping the ball outside the wall...
joxnas
Added more info too
colithium
Hey, thanks for your help. I will give you some votes when I can. I guess there's no efficient way to calculate the penetration depht for a general shape. I was doing this to learn, anyway, so I will probably move on.. maybe find a bad looking cheating method just to keep the things out the walls. About rotation, it is one of the things I wanna learn about too. Maybe now, maybe later. And friction is probably relativly simple.. But hey, I'm not planning to build my own engine, at least for now.. Even thought it's an appealing project for the future. Too bad my background in physics isnt great!
joxnas
I've had a year of physics at the undergrad level and some of the 3D game physics stuff is still over my head. But the nice thing about game physics is you can get really great stuff with pretty simple rules.For your demos you could simply give each object a radius even if it isn't a circle. Err on the side of too big. That should get you something at least. I'm sure algorithms exist that could calculate it exactly. There are 3D ones I know of (in the book I mentioned).
colithium
A: 

I did something a little like that and got a similar problem. What I did is that when the pixels from the bouncing object (a ball in your case) overlap with the pixels from the obstacle, you need to move the ball out of the obstacle so that they are not overlapping.

Say the ball is rolling on the obstacle, before your render the ball again you need to move it back by the amount of 'overlap'. If you know at what angle the ball hit the obstable just move it out along that angle.

You also need to add some damping otherwise the ball will never stop. Take a (very) small value, if the ball velocity is bellow that value, set the velocity to 0.

__dominic
But how many pixels I make the ball go back?Cause one can say: make it go back until it doesnt touch the surface anymore. But knowing that requires moving a pixel at a time and check if it is already not touching..which is a very intensive process for CPU. Let me know if I'm beeing stupid or misunderstood something in your answer.. :) thanks.
joxnas
You have all the variables you need to calculate how far you must move away from the "wall". First find the center point between your two "keypoints". Then measure the distance to this point from the center of your ball. Then minus that distance from your ball radius, and you've got the distance you need to move the ball away. Then you just need to get the angle to move it in.
TandemAdam
This is supposed to work with all kind of shapes, not just balls..
joxnas
In that case you will probably need to add different type of collision handlers depending on what object it colliding with what obstacle. I've read some of this book, it might be what you need:http://www.ebookpdf.net/__real-time-collision-detection-ebook_ebook_.htmlIt's probably not a very good idea to try and make one generic function that handles all type of collisions. But if you know by how much the object overlap when there is a collision, you need to move the object back in the opposite direction by the magnitude of the overlaping vector.
__dominic