@alkolove1

Как сделать абсолютно упругое столкновение окружностей?

Как сделать абсолютно упругое соударение ball's ?
Оно как бы резиново рикошетит от того круглого значка.
giphy.gif

Бокс2д не стал прикручивать, так как там слишком много ненужных мне переменных обрабатываются, неоптимизировано будет в мясных ситуациях.

ф-ция этого самого рикошета:
boolean collision(float Radius2, float X2, float Y2) //R1 - мяч, R2- объект, XY1- мяч, XY2- объект dx dy - скорость мяча
    {
        Circle ball = new Circle();
        ball.radius = Radius / 2;
        ball.x = rect.x + ball.radius;
        ball.y = rect.y + ball.radius;

        Circle obj = new Circle();
        obj.radius = Radius2 / 2;
        obj.x = X2 + obj.radius;
        obj.y = Y2 + obj.radius;


        if (ball.overlaps(obj)) {
            Vector2 otskok = new Vector2();
            otskok.x = ball.x - obj.x;
            otskok.y = ball.y - obj.y;

            Vector2 currentMov = new Vector2();
            currentMov.x = rect.dx;
            currentMov.y = rect.dy;
            Vector2 newDir; 
            newDir = currentMov.add(otskok);
            rect.dx = newDir.x;
            rect.dy = newDir.y;
            return true;
        } else return false;
    }


Где rect.x rect.y rect.dx rect.dy - позиция и приращения координат мячика. Потом его переделаю с ректангла на Сёркл, в данной ф-ции всё равно присваиваются параметры в сёркл, поэтому пока что это не принципиально.

ТЕОРЕТИЧЕСКИ я и сам знаю, что при детекте коллизии нужно тут же за один кадр вытолкнуть мяч на сумму радиусов обоих окружностей. Это я вычислить могу. Но вот угол смещения.
Да и вообще, мне кажется, у меня халтурный код, и можно как-то компактнее сделать, тем более средствами Libgdx, где есть векторные классы. Я просто нубчик в этом деле. Помогите. Умоляю...
  • Вопрос задан
  • 398 просмотров
Пригласить эксперта
Ответы на вопрос 1
@alkolove1 Автор вопроса
Чуть переделал код
Столкновение стало абсолютно упругим. Но мяч под некоторыми углами довольно резко сменяет позицию.
Всё-таки костыльный вариант с циклом пересечения не самый удачный.

boolean collision(float Radius2, float X2, float Y2) 
    {
        Circle ball = new Circle();
        ball.radius = Radius / 2;
        ball.x = rect.x + ball.radius;
        ball.y = rect.y + ball.radius;

        Circle obj = new Circle();
        obj.radius = Radius2 / 2;
        obj.x = X2 + obj.radius;
        obj.y = Y2 + obj.radius;

        if (ball.overlaps(obj)) {

            while (ball.overlaps(obj)) {
                double xDelta = (ball.x + ball.radius / 2 + rect.dx) - (obj.x + obj.radius / 2);
                double YDelta = (ball.y + ball.radius / 2 + rect.dy) - (obj.y + obj.radius / 2);
                rect.dx = (float) xDelta;
                rect.dy = (float) YDelta;
                ball.x+=rect.dx*Gdx.graphics.getDeltaTime();
                ball.y+=rect.dy*Gdx.graphics.getDeltaTime();
            }
            rect.x=ball.x-ball.radius;
            rect.y=ball.y-ball.radius;
            return true;
        } else return false;
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы