Computing a collision for a moving circle without overlapping boundaries
Let's say I have a circle bouncing inside a rectangular area. At some point, this circle will collide with one of the surfaces of the rectangle and reflect it back. The usual way I would do this so that the circle overlaps this border and then reflects the velocity vector. The fact that the circle actually overlaps the border is usually not a problem and is not noticeable at low speeds. At high speed, it becomes abundantly clear that the circle is doing what it shouldn't.
What I would like to do is programmatically take reflection into account and place the circle in the correct position before displaying it on the screen. This means that I have to calculate the point at which it hits the boundary between the current position and the future position, rather than calculating its new position and then checking if it hits the boundary.
This is slightly more complex than the usual circle / rectangle collision problem. I have a vague idea of how I should do this - basically create a bounding rectangle between the current position and the new position, which causes a lot of problems with this (since the rectangle rotates according to the direction of the circle speed). However, I think this is a common problem and that a common solution already exists.
Is there a general solution to this problem? Perhaps some basic theories I should be looking at?
a source to share
Since you just have a circle and a rectangle, it's actually pretty simple. A circle of radius r
bouncing inside a rectangle of dimensions w, h
can be handled in the same way as a point p
in the center of a circle, inside a rectangle (w-r), (h-r)
.
Updating a position is now easy. Given your point in position x, y
and the speed of each frame dx, dy
, the updated position x+dx, y+dy
is - except when you cross a border. If, say, you end with x+dx > W
(giving W = w-r
), then you do the following:
crossover = (x+dx) - W // this is how far "past" the edge your ball went
x = W - crossover // so you bring it back the same amount on the correct side
dx = -dx // and flip the velocity to the opposite direction
And similarly for y
. You will need to set up a similar (reflected) check for opposite bounds in each dimension.
a source to share
At each step, you can calculate the predicted / expected position of the circle for the next frame.
If it lies outside the rectangle, then you can use the distance from the old position of the circle to the edge of the rectangle and the amount "past" the edge of the rectangle where the next position lies (intermediate) to linearly interpolate and determine the exact time when the circle "hits" edge of the rectangle.
For example, if the circle is 10px from the edge of the rectangle, then it is supposed to move 5px outside of it, you know that for 2 / 3rds time (10 / 15th) it moves along the original path, then is reflected and continues on a new path for the remaining 1/3 of the time stamp (5/15). By calculating these two parts of the movement and "adding" the translations together, you can find the correct new position.
(Of course, it gets more complicated if you hit a corner, as there can be multiple collisions during the timestep, from different edges. And if you have more than one circle, things get a lot more complicated. Which is where you can start a business about which you asked)
a source to share