collision detection function in objective-c/core graphics
Is there a built-in function to detect collision between two circles?
I开发者_运维百科 have used CGRectIntersectsRect(rect1,rect2)
to
find the intersection between two rectangles.But if I want to know in which axis x or y they intersect how will i find it?
Is there a built-in function or do you have any other ideas?
If they're circles, the collision point (if it exists) will lie on the line connecting their centres, and the impulse to each will act in the direction from that point to the circle's centre.
Assuming centres (x1, y1)
and (x2, y2)
and radii r1
and r2
, the circles collide when
(x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) = (r1 + r2) * (r1 + r2)
This is just your basic Pythagorean theorem.
In most cases -- undoubtedly including yours -- collision detection is an approximate rather than analytic business. Which is to say, you move your objects by small steps and test for overlap, rather than solving the motion equations for the exact instant of contact. So instead of looking for the above case, you will use an inequality like this:
(x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) <= (r1 + r2) * (r1 + r2)
When this evaluates as true, the collision has basically already occurred, and you have two choices: you can work backwards to calculate exactly when and where that happened, or you can assume that your time steps are small enough that the time you notice an overlap is close enough to the moment of contact that it will serve as a reasonable substitute. Again, it is very likely this is what you want to do, but be aware that this is quite inexact: if your objects are moving quickly with respect to their size then it may look quite wrong, or even miss collisions altogether (sometimes humorously referred to as "quantum tunneling").
Since the circles probably overlap a little, you need to determine a proxy contact point -- let's call it (xp, yp)
. Since it's an approximation, there are several ways you might to choose to calculate it, but one reasonable choice might be:
xp = x1 + (x2 - x1) * r1 / (r1 + r2)
yp = y1 + (y2 - y1) * r1 / (r1 + r2)
That is, on the line between the centres, at a distance in proportion to the radii. If the overlap is small, this should be pretty close to the real collision point. If it's big, you're in trouble anyway.
Ignoring any rotation, each circular object will experience a push from this collision point towards its own centre. Eg, the push on object 1 will act in the direction (x1 - xp, y1 - yp)
.
To work out what the effect will be -- ie, how the objects will move afterwards -- you need to take into account the mass of each object and apply the law of conservation of momentum. Read up on elastic collisions and possibly, if you want to simulate collisions that are not perfectly elastic, the coefficient of restitution.
In the special case that the objects are the same size and mass and the collision is perfectly elastic -- which seldom occurs in real life but slightly more often in games -- you can break down the velocity of each object into the components parallel and perpendicular to the line between the centres, and then just swap the parallel components between the two objects.
If they're circles, the test is trivial. Just compare the distance between their centers to the sum of their radii.
精彩评论