![]() |
|
2D surface normals & physics |
Wes Jowitt
Member #4,657
May 2004
|
well, my craptacular but slowly functioning 2d physics/collision system is getting better by the minute. im currently working on implamenting dynamics of collisions (changes in angular and linear velocities, all the fun stuff). well, im not so great with my vector math anymore so i ran into a small problem... currently, im working on a simple perfectly elastic collision between two objects (all objects in my game are one of 4 shapes -- POINT, CIRCLE, BOX (can be rotated), and LINE) im working on circle->circle collisions at the moment. the detection is fine, but i need to calculate a few things in order to fix overlap and handle the dynamics.. for overlap: im attempting to simply nudge two objects off each other, and im attempting to push each object Obj1: CollisionSurfaceNormal*(0.5*PenetrationDepth) however, im not sure how to properly get the collisionSurfaceNormal...mostly due to the fact that i cant seem to be able to figure out how to get the point of collision of the objects. i was thinking i could approximate the normal by getting the Vector from body1 midpoint to body2 midpoint and normalize it, but if both circles happen to overlap perfectly (or if they both happen to be POINTs) the normal vector will be 0...
|
X-G
Member #856
December 2000
![]() |
Points have no size, and can't collide. They are not an issue. Circles should never perfectly overlap. Construct your system so that that can never happen. The face normal in 2D space is (-y, x), where x and y are the components composing the wall vector (between the two endpoints). -- |
Tobias Dammers
Member #2,604
August 2002
![]() |
Quote: Circles should never perfectly overlap. Construct your system so that that can never happen. You should still catch this scenario, just in case the system doesn't do what it should. If the vector is 0, then throw a debug message (e.g. TRACE() ) and do no collision at all. This means that objects could theoretically go through each other, but this will only happen if your system fails (normally, circles should first overlap "normally" and only if you don't handle that, they will overlap "perfectly"), so that won't be an issue in practice. --- |
gillius
Member #119
April 2000
|
The normal at any point on a sphere points away from the center. You can calculate it thusly: Vector2 collisionPoint = getIntersectionPoint(); Vector2 normal = collisionPoint - getCircleCenterPoint(); normal.normalize(); For two collisions between spheres, that is easy. Subtract the two center points and normalize. This is called the moment of collision or something like that -- I forget. Gillius |
Plucky
Member #1,346
May 2001
![]() |
Since computing the surface normal of a sphere-sphere collision is simple once you know the the point of contact, the problem is finding that collision point. (Center to center vector is not generally the surface normal of the collision if there is any overlap unless the spheres were moving in directly opposite directions.) With the last velocity vector for each sphere, turn it into parametric form (which it likely already is, with x1 = x0 + vt where t, the parameter, is generally one). Find t such that the distance between the 'x1' points for both spheres are the sum of the radii. This will give you the locations of both centers of spheres at the instant of contact. |
Thomas Harte
Member #33
April 2000
![]() |
Another solution is to do as I do - don't allow objects to overlap at any time. This is simply a matter of calculating collisions not as 'do these objects overlap' but as 'if these objects continue moving like this, will they collide and if so then when?' Game loop is then, per frame:
You have to throw in a few checks to make sure that numerical accuracy errors don't lead to infinite loops, but that's all pretty obvious. Also, you probably want to implement clever sweep/search algorithms and such like to speed up the 'for(all objects...' test. As I usually get laughed out of the thread for suggesting these sort of things, attached is a demo showing collisions using the above algorithm between three of the types of object you describe - box (the weird green skinned fellow is modelled so), circle and line (the screen boundaries). Keys are: cursors - move man It was going to be a Robotron type affair. Probably still will be one day. Uninterestingly to the thread, hit 'q' or 'w' to see the explosion / bonus effects that I had intended to use. Alt+enter toggles full screen or not. Collisions are full elastic, but note that by moving the man, you are adding energy to the scene, so if he hits a ball while moving, it'll gain energy. He has a lot of mass! An x-axis sweep test is used to quickly throw away a whole bunch of potential collisions, and spatial coherences (i.e. sorted x-projected list of sprites is liable to be similar frame on frame) are exploited to speed everything along. Basic attempts at avoiding numerical errors are made, but they do collapse once you have 1000s of objects on screen, and lead to a little character wobbling if you try and leave the screen. OpenGL is used for drawing. [My site] [Tetrominoes] |
|