# A ball hits the corner, where will it deflect?

I need to brush up my trigonometry and hope you can help here with a simple mathematical model. Here is my model so far in the image attached. I am aware that the frame animation has other problems when the ball is moving very fast, but for now I just need to calculate ballDx and ballDy. It is also possible that ballDx = 0 (vertical movement only), but when the ball deflects ballDx may get a different value.

-
Is this what they call a "corner case"? – Andrew Grimm Apr 11 '11 at 2:30
Definitely, as things go, soon we may employ the theory of relativity to solve it – the problem is getting mass(ive). – Lumis Apr 13 '11 at 23:18

Note: All of the following assumes the ball's surface is frictionless (so it won't start spinning or rebound differently because it is).

At the moment of collision, the ball will be touching the corner. When solid objects collide, a force will act along the so called surface normal, i.e. perpendicular to the surface at the point of collision.

Since it's a ball, perpendicular to the surface is towards to ball's center. Ok, so we know the direction of the force, what about its magnitude? Assuming an elastic collision (and that the rectangle can't move), the ball must rebound at the same velocity it impacted with.

Let (nDx, nDy) be the velocity after collision, (oDx, oDy) the velocity before collision, and (x,y) the position of the ball at the point of collision. Let's further assume the corner the ball collides with is at (0,0).

Expressing our insights as formulae, we have:

``````(nDx, nDy) = (oDx, oDy) + c * (x, y)
length (nDx, nDy) = length (oDx, oDy)
``````

Which is equivalent to:

``````nDx = oDx + c * x
nDy = oDy + c * y
nDx^2 + nDy^2 = oDx^2 + oDy^2
``````

Substituting the first two equations in the last one, we get:

``````(oDx + c * x)^2 + (oDy + c * y)^2 = oDx^2 + oDy^2
``````

Expanding using the binomial thorem

``````(a+b)^2 = a^2 + 2ab + b^2
``````

yields:

``````oDx^2 + 2 * oDx * c * x + (c * x) ^ 2 + oDy^2 + 2 * oDy * c * y + (c * y) ^ 2 = oDx^2 + oDy^2
2 * oDx * c * x + 2 * oDy * c * y + (c * x) ^ 2 + (c * y) ^ 2 = 0
(2 * oDx * x + 2 * oDy * y) * c + (x^2 + y^2) * c^2 = 0
``````

This quadratic equation for `c` has two solutions, one of which is 0. Obviously, that's not the solution we are interested in, as generally the direction of the ball will change as a result of the collision. To get the other solution, we divide both sides by c and get:

``````(2 * oDx * x + 2 * oDy * y) + (x^2 + y^2) * c = 0
``````

That is:

`````` c = -(2 * oDx * x + 2 * oDy * y) / (x^2 + y^2)
``````

To summarize, we have:

``````c = -(2 * oDx * x + 2 * oDy * y) / (x^2 + y^2)
nDx = oDx + c * x
nDy = oDy + c * y
``````

Edit: In code:

``````if (collision) {
float x = ballX - cornerX;
float y = ballY - cornerY;
float c = -2 * (ballDx * x + ballDy * y) / (x * x + y * y);
ballDx = ballDx + c * x;
ballDy = ballDy + c * y;
}
``````

A few implementation considerations: While you can approximate (x,y) with the ball's position after the simulation step, this approximation will change the angle of deflection and hence be very noticeable, so your simulation steps need to be very fine (perhaps such that the ball doesn't move more than 1/20 of its diamater per step). For a more accurate solution, you could compute the time the collision occurs, and split that simulation step at that time, i.e. do a partial step until the point of collision, and another partial step for the remainder of the step.

Edit 2: Computing the point of impact

Let r be the radius, (x0, y0) the position and (dx, dy) the velocity of the ball at the beginning of the simulation step. For simplicity, let's further assume that the corner in question is located at (0,0).

We know:

``````(x,y) = (x0, y0) + (dx, dy) * t
``````

We want

``````length(x,y) = r
``````

That is

``````(x0 + dx * t) ^ 2 + (y0 + dy * t) ^ 2 = r^2
x0^2 + 2 * x0 * dx * t + dx^2 * t^2 + y0^2 + 2 * y0 * dy * t + dy^2 * t^2 = r ^ 2
(dx^2 + dy^2) * t^2 + (2 * x0 * dx + 2 * y0 * dy) * t + (x0^2 + y0^2 - r^2) = 0
\____  _____/         \____________  ___________/       \_______  ________/
\/                            \/                           \/
a                             b                            c
``````

That is a quadratic equation in t. If its discriminant

``````D = b^2 - 4 * a * c
``````

is negative, it has no solutions, i.e. the ball will never hit the corner on its present course. Otherwise, its two solutions are given by

``````t1 = (-b - sqrt(D)) / (2 * a)
t2 = (-b + sqrt(D)) / (2 * a)
``````

We are interested in the time the collision started, which is the earlier time `t1`.

``````    // compute a,b,c and D as given above

if (D >= 0) {
t = (-b - sqrt(D)) / (2 * a);
if (0 < t && t <= ts) {
// collision during this timestep!

x = x + t * dx;
y = y + t * dy;
ts = ts - t;

// change dx and dy using the deflection formula
}
}

x = x + ts * dx;
y = y + ts * dy;
``````
-
this deserve +1 – dynamic Apr 10 '11 at 17:09
Feel free to upvote, then :-) – meriton Apr 10 '11 at 17:52
You say very early that `At the moment of collision, the ball will be touching the corner` but I don't see a justification of this approximation (and it must be an approximation because it's not true - the ball is touching in two places, neither of which is the corner). – Peter Taylor Apr 11 '11 at 12:28
@Peter Taylor: You did notice that the OP has drawn the ball outside the rectangle, and the collision detection formula given in the question assumes this, too? You gotta think outside the box here :-) – meriton Apr 11 '11 at 21:35
Love this answer, but it could use some \$\LaTeX\$ markup of the math. – Martin Wickman Apr 13 '11 at 20:44

Here's a visual way of looking at a problem.

The original problem set is circle vs. rectangle (gray in the image below). This is equivalent to point vs. rounded rect (shown in black).

So this is a multi-part problem. You're testing your point collision vs. 4 lines (extruded out from the edge of the box by the radius of the original circle) and 4 circles (at the corners of the rectangle with the same radius of the original circle).

With the rough velocity in your original image, the point will hit the bottom right corner circle. All you have to do is figure out the point on the corner circle that you would hit, calculate the angle of that, and reflect off of it.

I'll leave the derivation of that as an exercise to the reader.

-

I'm working on a game and also stuck here. But I guess it goes this way:

//Image in the next comment

There's another view My problem is that I don't know how to quickly calculate the new dx, dy (to me using traditional math requires too many calculations).

-
Your image link link has virus attached to that website! – Lumis Apr 10 '11 at 10:39
Oh, I'm so sorry. I always use that site to upload images and never seen any problem. Photobucket is safe then: i763.photobucket.com/albums/xx274/fleuve_rouge/… – Risa Apr 10 '11 at 11:26
I've just had to restore my windows to a previous retore point. That link installs an exe file which pretends to be anti-virus software. My firewall stoped it communicating but it still overtook my PC. You better remove the "imege link", that webiste could be compromised! – Lumis Apr 10 '11 at 11:35
I'm so sorry about the incident (everything still works fine in my PC thought). Does the Photobucket link work for you? (I guess it does because Photobucket is a famous site). My point of view is different to the one in the 2nd link, because I don't think the new velocity vector depends on the center of the block like that. My brother told me the ball will bounce back to the old direction (dx = -dx && dy = - dy) but I don't think so. – Risa Apr 10 '11 at 12:06
For future reference, there's a button in the post window that links to the official, stackexchange approved, image hosting service: imgur – Tetrad Apr 10 '11 at 13:43