8
\$\begingroup\$

I have a simple game in which the player moves a ball around. The ball bounces off of walls. Right now I have square walls(■) implemented: I use simple bounding-box collisions to check if the player will move into a wall when updating its x or y speed and if so, I multiply that speed with -1 to make them bounce.

However, I also want to implement triangular pieces(◢◣◤◥). To bounce back I believe one can simply use:

   newxspeed = -1*yspeed;
   newyspeed = -1*xspeed;

However, what I am having trouble with is the collision detection: When does the player hit the diagonal?

\$\endgroup\$
  • 2
    \$\begingroup\$ I highly recommend the N tutorial (part 1, part 2) on this topic. \$\endgroup\$ – Chris Burt-Brown Oct 13 '13 at 12:58
  • \$\begingroup\$ Thank you very much. That tutorial actually helped me to finally understand how to solve this. \$\endgroup\$ – Qqwy Oct 14 '13 at 16:24
  • \$\begingroup\$ Actually it is very hard for me to mark one of the answers as 'the' solution since all of them helped me to understand the problem but none of them fully solved it. What should I do? \$\endgroup\$ – Qqwy Oct 14 '13 at 16:33
8
\$\begingroup\$

First of all in order to calculate the collision detection between a sphere(circle in 2D) and a line you need to calculate the perpendicular vector between the moving ball's center and the line, in order to calculate this distance you need to do the following:

enter image description here

So in order to calculate d in the above figure we need to do some steps.

  1. Assume your line is using the parametric equation P(t) = S + t V note that V is the line direction can be obtained by subtracting (P2 - P1).
  2. From Pythagoras:

d^2 = len(Q - S)^2 - len( proj(Q - S ) )^2

Then you expand the equation to get the following, it seems a bit complicated but it's actually not.

d = sqrt( len(Q - S)^2 - len( (Q - S) dot V )^2 / V^2 )

Where Q is the circle's center and S is any point on the line. Once the distance is less than the circle/sphere radius you need to trigger collision response which is explained in the next point.

It's incorrect to always flip the x or y component to bounce the ball, what you need to do is to reflect the velocity vector, in order to do so you need to calculate the Normal vector of the surface and use that normal for calculating the reflection vector using the following equation

R = 2 * (V dot N)* N - V

where R is the reflection vector, N is the normal of the surface and V is the Velocity vector.

In case of 45 deg your surface normal will be N = (1,1,0) with varying sign depending on which direction the normal faces (position or negative).

\$\endgroup\$
  • \$\begingroup\$ You use a great equation. However, it is very hard to follow for someone who is new to vectors. It would be helpful if you split up your equation in smaller steps. \$\endgroup\$ – Qqwy Oct 14 '13 at 16:26
  • \$\begingroup\$ By the way, is N a 2-dimensional or a 3-dimensional vector? Where does the third value (0) come from? \$\endgroup\$ – Qqwy Oct 14 '13 at 16:37
  • \$\begingroup\$ I used 3D vectors because I assumed you are using a 3D API (and I might be wrong) in case it was true you need to set the 3rd component as 0, but anyway the equations should work for both 2D and 3D (and probably higher dimensions but that doesn't really matter). regarding the equations I can explain more but I need some time editing the answer. \$\endgroup\$ – concept3d Oct 14 '13 at 17:49
  • 1
    \$\begingroup\$ I edited the answer I hope it makes more sense now.. btw I hope stackexchange can provide a convenient way to write mathematical formulas because it's pain and error prone right now. \$\endgroup\$ – concept3d Oct 14 '13 at 18:30
6
\$\begingroup\$

You want to measure the distance between the center of your ball and the wall, so:

enter image description here

solving the system that you see in the picture will give you the coordinates of point d.

Then, if the distance between point d and c is smaller or equal to the radius of the ball r, there is a collision between the ball and the wall

\$\endgroup\$
5
\$\begingroup\$

Balls are actually rather simple objects for collision detection. They collide with terrain when the distance between the ball's center and the edge of the terrain becomes less than the ball's radius. The position of the center of the ball should be trivial to obtain. Finding the nearest point of terrain is generally more complicated and the best way to do it depends on how the terrain is represented.

Your algorithm to calculate the new velocity after bouncing off a diagonal slope is incorrect. Inverting both the x- and y-coordinates will make the ball go back in the same direction it approached the slope from. This is fine if the ball comes at the terrain from a right angle, but fails for other angles. You'll want to negate only the component normal to the surface, e.g. when bouncing off the ceiling, you negate y, not x.

\$\endgroup\$
  • \$\begingroup\$ Although this answer does not directly approach the problem, +1 for telling me about the way collision resolution should be done in this case. \$\endgroup\$ – Qqwy Oct 14 '13 at 16:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.