Rebounding angle of two Circles

2

How can I calculate the bounce angle between two circles ... ??

I use the following code to check and resolve collisions.

-- CHECK COLLISIONS BALLS AND RESOLVE ...
function CheckCollisionResolve(a, b)
    local dx = a.x - b.x;
    local dy = a.y - b.y;
    local d = math.sqrt(dx*dx + dy*dy);

    local minDist = (a.radius+b.radius);
    local midpointx = (a.x + b.x) / 2;
    local midpointy = (a.y + b.y) / 2;

    if d <= minDist then
        -- RESOLVE POSITION BALLS ...
        a.x = midpointx + a.radius * (a.x - b.x) / d;
        a.y = midpointy + a.radius * (a.y - b.y) / d;

        b.x = midpointx + b.radius * (b.x - a.x) / d;
        b.y = midpointy + b.radius * (b.y - a.y) / d;

        return true;
    end

    return false;
end

everything works fine, but if there is no reaction from the angle there is no very satisfactory or realistic effect when trying to resolve the collisions.

This is the code that moves the circles and checks the collisions.

-- UPDATE BALLS ...
function update_balls(dt)
    local lenBalls = #balls;

    for i = 1, lenBalls do
        local ball = balls[i];

        -- CALCULATE NEW POSITION ...
        local theta = ball.angle * (math.pi/180.0);
        ball.x = ball.x + ((ball.speed * dt) * math.cos(theta));
        ball.y = ball.y + ((ball.speed * dt) * math.sin(theta));

        -- CHECK BALL COLLISION TO SCREEN HORIZONTAL.
        if ball.x-ball.r < 0 then
            ball.x = ball.r;
            ball.angle = reflectHorizontalAngle(ball.angle);
        elseif ball.x+ball.r > sw then
            ball.x = sw-ball.r;
            ball.angle = reflectHorizontalAngle(ball.angle);
        end

        -- CHECK BALL COLLISION TO SCREEN VERTICAL
        if ball.y-ball.r < 0 then
            ball.y = ball.r;
            ball.angle = reflectVerticalAngle(ball.angle);
        elseif ball.y+ball.r > sh then
            ball.y = sh-ball.r;
            ball.angle = reflectVerticalAngle(ball.angle);
        end
    end

    -- CHECK COLLISIONS BALLS RESOLVE ...
    for i = 1, lenBalls do
        for j = 1, lenBalls do
            if i ~= j then
                local col = CheckCollisionResolve(balls[i], balls[j]);
            end
        end
    end
end

This is the code I use to calculate the bounce angles with the walls (horizontal and vertical).

-- REFLECT ANGLES VERTICAL AND HORIZONTAL ...
local reflectVerticalAngle = function(angle) return (360 - angle) < 0 and ((360 - angle) + 360) or (360 - angle); end;
local reflectHorizontalAngle = function(angle) return (180 - angle) < 0 and ((180 - angle) + 360) or (180 - angle); end;

the speed of the circles is constant without variation, since I am working with angles.

I hope you can help me.

    
asked by luislasonbra 08.06.2017 в 18:30
source

1 answer

3

I think the solution happens more in this case for a geometry issue and understand how the coordinate system works with love2d

Look at the following scheme If you look at the reference system of the aforementioned SDK, take as the starting point, the upper left part of the monitor in a clockwise direction, actually the diagram I have shown can be done in different ways (isosceles triangle, parallel, etc) but I prefer to apply the third law of newton ... that is, the angle at which the wall will hit will be the angle of rebound but with a changed sign.

Regarding the code, I do not know how many little balls there will be in the application, but what I do suggest is the intensity of the calculation that you are going to apply, declare the global variables as local variables, and that the local variables declare them outside the loop for to improve the performance of the code, leaving something like this:

-- Funciones de ayuda
-- deben estar al inicio de todo el archivo
-- es una buena práctica para mejorar el rendimiento
-- del código
local cos=math.cos
local sin=math.sin
local rad=math.rad

-- UPDATE BALLS ...
function update_balls(dt)

    local theta -- no importa que no le asignes valor inicialmente
                -- ya que Lua no requiere que se le defina el tipo
                -- de variable que va ser, es decir puede ser string
                -- y luego convertirse en number esto es sumamente útil, por ejemplo:
                -- local a = "10"; print(type(a)) -- se imprime: string
                -- a = a + 0; print(type(a))      -- se imprime: number

    for _, ball in pairs(balls) do

        -- CALCULATE NEW POSITION ...
        theta = rad(ball.angle)
        ball.x = ball.x + (ball.speed * dt) * cos(theta)
        ball.y = ball.y + (ball.speed * dt) * sin(theta)

        -- el resto del código
    end

end
    
answered by 30.05.2018 в 06:46