views:

162

answers:

3

Does anyone know a very simple physics engine, or just a set of basic functions that could complete these tasks: Simple point, line, and rectangle collision detection? I looked at Box2D but it is way too advanced for what I am making. I just need some simple code. Thanks in advance!

+1  A: 

If you need simple 2d collision detection, it's very simple and there's lots of game dev tutorials available, see for example http://www.gamedev.net/reference/articles/article735.asp.

A: 

Is there a reason you couldn't use basic geometry for this?

Two points collide when their coordinates are the same.

A point intersects with a line when its position is a solution to the equation for the line.

A point intersects a rectangle when the point is bounded by the rectangle.

More complex composite cases can be constructed by composing these cases. Were you specifically looking for a library for some reason?

Gian
I kinda just wanted to see if it was already done before I started messing with it. I really hate geometry...
Matt
Fair enough. I'm a fan of code reuse and all that, but in truth it's probably necessary for you to know enough about this in order to implement the rest anyway that perhaps it's worth exploring further.
Gian
Pet-peeve of mine: None of these are collision tests, but intersection tests. And in simulations, an intersection test is almost *never* the solution. How often is a point going to coincide perfectly with a line, or even another point? To get the right idea, you need to sweep objects out over the course of the time interval you're checking. A basic dynamic point to static line collision test would sweep the point out into a line (based on velocity and time interval), then do a line-line intersection test. Collision detection isn't trivial, and I highly recommend using an existing library.
GMan
I respectfully defer to your (quite correct!) criticism. I guess that's a sufficient answer to the question "Is there a reason you couldn't use basic geometry for this?" :p
Gian
+2  A: 

Here's my shot at point/line collision detection. The important thing is to avoid trig functions, divisions, and other expensive operations so as not to slow things down too much.

As GMan's comment notes, you need to bear in mind that the point will be moving. So you'll have the current position of the point (let's call it A) and the possible new position of the point (B). You need to find out if, when the point moves from A to B, it would collide with a line.

Let's call the start and end points of the line C and D. A collision will occur only if the lines AB and CD intersect.

Let's describe the line AB using the standard equation Ux + Vy + W = 0. After some algebra, the equation comes out as:

(ay - by) x + (bx - ax) y + ax by - bx ay = 0

We can describe the line CD in terms of a parameter t and constants X Y U V:

x = X + Ut
y = Y + Vt

It's helpful if we set t=0 at point C, and t=1 at point D. By considering t=0 we can work out X and Y. And by considering t=1 we can work out U and V. This gives

x = cx + (dx - cx) t
y = cy + (dy - cy) t

To find the intersection point of the two lines, substitute these into the equation we found for AB, which gives

(ay - by) (cx + (dx - cx) t) + (bx - ax) (cy + (dy - cy) t) + ax by - bx ay = 0

This reduces to

t = (ax by - bx ay + bx cy - cx by + cx ay - ax cy) / q

where q = (ay - by)(cx - dx) - (ax - bx)(cy - dy)

  • If q is zero, the lines are parallel and do not meet.
  • If 0 < t < 1 then the line extrapolated from AB intersects CD.

But we still don't know that this intersection is actually between the points A and B. So we need to repeat all the previous steps, swapping AB and CD, and writing the line AB in terms of a parameter s. This gives:

s = (cx dy - dx cy + dx ay - ax dy + ax cy - cx ay) / q
  • If 0 < s < 1 then the line extrapolated from CD intersects AB.

That's it. So in your code you start by calculating q. If q is zero then the lines are parallel. Otherwise, go on to calculate t and s. If 0 < t < 1 and 0 < s < 1 then a collision is about to happen. To find the location of the collision, substitute t or s back into the original equations for CD.

For extra speed you can remove the divisions by q - it's possible to just check whether the top half of each fraction is in the correct range, and then each check should only need 10 multiplication operations.

minimalis