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!
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.
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?
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 fromAB
intersectsCD
.
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 fromCD
intersectsAB
.
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.