
-----------------------------------
zwnage
Sun Jan 14, 2007 9:48 pm

Circle Collision-Help Needed
-----------------------------------
Hello. While looking up peoples sources to try and get ideas, I came across this neat snippet of code from a pool game:


angle := arctand ((ballY (k) - ballY (i)) / ((ballX (k) - ballX (i)))) % angle of hit

cosAngle := cosd (angle)
sinAngle := sind (angle)

speedAfterHit := (2 * ((ballXSpeed (i) * cosAngle + ballYSpeed (i) * sinAngle) - (ballXSpeed (k) * cosAngle + ballYSpeed (k) * sinAngle))) / (ballMass (i) + ballMass (k))

% new velocities of the balls
ballXSpeed (i) -= speedAfterHit * ballMass (k) * cosAngle
ballYSpeed (i) -= speedAfterHit * ballMass (k) * sinAngle
ballXSpeed (k) += speedAfterHit * ballMass (i) * cosAngle
ballYSpeed (k) += speedAfterHit * ballMass (i) * sinAngle


I tried a few test programs with that code, and it works a lot better than the code I'm trying to use, but I really want to learn how this code works, especially whats happening in speedAfterHit and why are we muiltiplying the trig ratios of the angle hit with the ball speeds. Can anyone please explain the code? Thanks.

-----------------------------------
Cervantes
Sun Jan 14, 2007 10:46 pm

Re: Circle Collision-Help Needed
-----------------------------------
First, have you checked this out? why are we muiltiplying the trig ratios of the angle hit with the ball speeds
This is very common. See, using cosd gives you a number between 0 and 1 that represents the length of a horizontal line from the origin to directly below the point.


     /|
    / |
   /  |    maxy - ballRadius (i) or ballY (i) < ballRadius (i) then
            ballYSpeed (i) *= -1
        end if


        ballX (i) += ballXSpeed (i)
        ballY (i) += ballYSpeed (i)
        Draw.Oval (round (ballX (i)), round (ballY (i)), ballRadius (i), ballRadius (i), black)
    end for
    delay (10)
    View.Update
    cls
end loop


Since I havn't taken physics yet (its next sem), I might have mixed up a few terms. The velocities might be called speed or momentem or something. 

Heres the jist of it:

find a hit

find the distance traveled each frame by both the balls before the hit (speed or velocity or whatever you call it)---ie : ballVelocity := ((ballXSpeed (i) ** 2 + ballYSpeed (i) ** 2) ** 0.5)

find the angle the ball was originally travelling at. -- ie : ballVelocity := ((ballXSpeed (i) ** 2 + ballYSpeed (i) ** 2) ** 0.5)

calculate the new velocities by subtracting the balls velocity by the other balls velocity, thus slowing the ball down or reversing the direction.-- ie :ballNewVelocity := ((((cosd (ballVelocityAngle)*ballVelocity - cosd (ballVelocityAngle2)*ballVelocity2) ** 2) + (sin (ballVelocityAngle)*ballVelocity) ** 2) ** 0.5)

calculate the new angle of bounce

use the angle of bounce and the new velocites to get the x and y speeds. 


Now this code is far from perfect. The program cannot account for when both balls goes hits while going in the same direction (ie : one is faster than the other and hits it from behind). The velocity minus part will slow one of the balls down like its supposed to, but the other ball is slowed too (and probably will go in the opposite direction, towards the first ball). This causes an overlap, and causes them to stick or fly away wildly. The solution I thought of is to give the velocites a positive or negative value, but that would mean I would have to divide my velocites into a further set: the x and y values, I think.....

I dunno if anyone can do anything with that snippet of code, but your welcome to try.

-----------------------------------
Ultrahex
Mon Jan 15, 2007 8:53 am

Re: Circle Collision-Help Needed
-----------------------------------
Just for your guys information, this is collision response, not collision detection correct?, so what you are trying to do is determine angular momentum, along with momentum, so you need to determine the new velocities along with the new direction.

For those who don't understand the collision detection:

The Collision of a Circle to a Circle is very simple, It is explained by the pictures below:

http://img181.imageshack.us/img181/2789/collisionimage1bl2.gif

http://img181.imageshack.us/img181/2672/collisionimage2oz7.gif

type Ball :
    record
        x : real
        y : real
        v : real % magnitude of velocity
        dir : real
        r : real
    end record

var balls : array 1 .. 2 of Ball

balls (1).x := 50.0
balls (1).y := 50.0
balls (1).v := 5
balls (1).dir := 180
balls (1).r := 40

balls (2).x := 150.0
balls (2).y := 150.0
balls (2).v := 5
balls (2).dir := 45
balls (2).r := 40

View.Set ("offscreenonly")
loop
    % Update Position
    for i : 1 .. upper (balls)
        % Wall Collision

        %---Horizontal
        if (balls (i).x + balls (i).r + cosd (balls (i).dir) * balls (i).v) >= maxx or (balls (i).x - balls (i).r + cosd (balls (i).dir) * balls (i).v) < 0 then
            balls (i).dir := -balls (i).dir + 180
            put balls (i).dir
        end if
        %---Vertical
        if (balls (i).y + balls (i).r + sind (balls (i).dir) * balls (i).v) > maxy or (balls (i).y - balls (i).r + sind (balls (i).dir) * balls (i).v) < 0 then
            balls (i).dir := -balls (i).dir + 360
        end if

        % Update x/y positon based on magnitude of velocity
        balls (i).x += cosd (balls (i).dir) * balls (i).v
        balls (i).y += sind (balls (i).dir) * balls (i).v
    end for


    % Drawing
    for i : 1 .. upper (balls)
        drawoval (round (balls (1).x), round (balls (1).y), round (balls (1).r), round (balls (1).r), red)
        drawoval (round (balls (2).x), round (balls (2).y), round (balls (2).r), round (balls (2).r), blue)
    end for

    % Circle-To-Circle Collison
    if sqrt ((balls (1).x - balls (2).x) ** 2 + (balls (1).y - balls (2).y) ** 2) 