Сохранение массы в 2D - PullRequest
       17

Сохранение массы в 2D

0 голосов
/ 05 февраля 2019

У меня есть эта программа, где шары отскакивают по экрану.Я хочу, чтобы шары могли отскакивать друг от друга.

Итак, у меня есть метод boolean intersects(ball b2) {. . .}, он проверяет, пересекается ли b. с b2.Если b.intersects (x) возвращает true, то вызываются calcDX() и calcDY().

void calcDX(Ball b2) {
    double b1Momentum = mass * dx;
    double b2Momentum = b2.mass * b2.dx;

    double b2FinalVelocity = (b1Momentum + b2Momentum + mass * (dx + b2.dx)) / (mass + b2.mass);

    dx = b2FinalVelocity - dx - b2.dx;
    b2.dx = b2FinalVelocity; //hi
}

void calcDY(Ball b2) {
    double b1Momentum = mass * dy;
    double b2Momentum = b2.mass * b2.dy;

    double b2FinalVelocity = (b1Momentum + b2Momentum + mass * (dy + b2.dy)) / (mass + b2.mass);

    dy = b2FinalVelocity - dy - b2.dy;
    b2.dy = b2FinalVelocity;
}

Так что это уравнение для упругих столкновений, которое я использую, где dx и dy - это изменение x и y.

Итак, у меня есть этот цикл (я знаю, while(true), игнорируем его), который обновляется 60 раз в секунду, чтозвонки updateBallPositions() каждый раз

@Override
public void run() {
    int ticksPerSecond = 60;
    long lastTime = System.nanoTime();
    double nanoSecondsPerTick = 1000000000.0 / ticksPerSecond; // How many nano-seconds in a tick
    double delta = 0.0;

    while (true) {  // main game loop
        long now = System.nanoTime();
        delta += (now - lastTime) / nanoSecondsPerTick;
        lastTime = now;

        while (delta >= 1) { // tick
            delta -= 1;

            updateBallPositions();
            f.panel.repaint();
        }
    }
}

private void updateBallPositions() {
    for (Ball b : balls) {
        b.x += b.dx;
        b.y += b.dy;

        for (Ball b2 : balls) {
            if(b != b2 & b.intersects(b2)) {
                b.calcDX(b2);
                b.calcDY(b2);
            }
        }

        if(b.isTouchingHorizontalWall(f))
            b.dy *= -1;
        if(b.isTouchingVerticalWall(f))
            b.dx *= -1;
    }
}

Все это прекрасно, но не работает.Шары часто слипаются и сталкиваются навсегда, в то время как шары должны плавно подпрыгивать.(Если вам нужно больше кода, скажите так)

1 Ответ

0 голосов
/ 05 февраля 2019

Ваша обработка столкновения выглядит неправильно.

Пусть шар A имеет массу ma, вектор скорости VA0
Пусть шар B имеет массу mb, вектор скорости VB0
Они сталкиваются в точке C
. Чтобы вычислить скорости после столкновения, мы должны использовать закон сохранения энергии и закон сохранения импульса

Рассмотрим временные оси:
T -касательные к обоим шарам через точку C и радиальные R соединяющие центры шариков

enter image description here

Проекции скоростей на T являются тангенциальными векторами (дляНапример, VAt), по оси R - радиальные векторы (например, VAr)

Важно - тангенциальные импульсы не изменяются во время столкновения: VAt1=VAt, VBt1=VBt

Таку нас есть уравнения в T-R системе координат

 ma * VAr + mb * VBr = ma * VAr1 + mb * VAr2
 ma * VA0^2 + mb*VB0^2 = ma * VA1^2 + mb*VB1^2   // I removed division by two
 but
 VA1^2 = VAr1^2 + VAt^2
 VB1^2 = VBr1^2 + VBt^2

так, наконец, система из двух уравнений с двумя неизвестными VAr1, VBr1

 ma * VAr + mb * VBr = ma * VAr1 + mb * VAr2
 ma * VA0^2 + mb*VB0^2 = ma * (VAr1^2 + VAt^2) + mb*(VBr1^2 + VBt^2)

Решите это, преобразуйте компоненты скорости в мировую систему координат OXY

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...