cwheats
cwheats

Reputation: 13

How to detect the point of collision between two circles and then create a vector to update the circle's position?

i'm writing a simple air hockey style game in CodeSkulptor (python 2). 3 circles, basically two paddles and a ball. I understand how to detect collisions between circles, but I have found it difficult to then accurately model how that circle would bounce off a user controlled circle. The user controlled circle (paddle) tends to consume the ball and the ball gets stuck. I think my code for the ball bouncing off a wall is pretty much the same as the code I wrote for the paddle collision.

I read a bit around some other posts and i've figured out that I need to get the point of collision and then somehow turn that into a vector to update the ball's position. Can anyone help me with that? Also, does the fact that the paddle is user controlled complicate things? I'm guessing the impact on the ball has to take into account the vector of the paddle as well?

Thanks for any responses, and please keep the maths as simple as you can.

Chris

Upvotes: 0

Views: 1079

Answers (1)

User
User

Reputation: 14853

Solution 1

The algorithm that works well for me and arbitrary shapes is

  1. move the circle
  2. test if it overlaps
  3. if it overlaps: move it back
  4. make it change the direction.

This way you should not get stuck if the other part is not moving in the mean time. Because by moving back you do not overlap afterwards and do mot trigger the bounce and change-direction twice.

Solution 2

Using vectors and only circles:

circle1x, circle1y, circle1radius, circle2x, circle2y, circle2radius

if (circle1x - circle2x) ** 2 + (circle1y - circle2y) ** 2 < (circle1radius + circle2radius) ** 2: 
    # they overlap using http://en.wikipedia.org/wiki/Pythagorean_theorem
    # compute new direction

Changing Direction

computing the new direction can just ignore the speed of both circles but that does not look quite natural.

 old_direction1 = (v1x, v1y)
 velocity1 = (v1x ** 2 + v1y ** 2 ) ** 0.5
 old_direction2 = (v2x, v2y)

 distance = ((circle1x - circle2x) ** 2 + (circle1y - circle2y) ** 2) ** 0.5
 new_direction1 = ((circle1x - circle2x) / distance * velocity1, 
                   (circle1y - circle2y) / distance * velocity1)
 new_direction2 = ((circle2x - circle1x), ...)

But you can use this new direction and the old direction to create a new direction that looks more natural. I did not test this out but it should look something like this:

combined_direction = old_direction + 2 * (old_direction dot-product new_direction) * new_direction

The dot product gives you the direction that is projected onto some vector have a read.

Also once you got this you can create elastic collisions considering how heavy the circles are: http://en.wikipedia.org/wiki/Collision

Upvotes: 1

Related Questions