прыгающие шары никогда не остаются спокойными на земле - PullRequest
4 голосов
/ 01 июня 2011

Я пытаюсь создать очень простой физический движок для моего исследования (обработка используется для интерактивной установки).

Цель состоит в том, чтобы земля была покрыта шарами, которые можно бросать жестами (на основеИнформация о Kinect).

Для этого мне нужно выполнить некоторые базовые физические симуляции, такие как прыжки и вот с чего я начал.Так что есть просто шары падают и подпрыгивают.Я смоделировал сопротивление воздуха простым умножением 0.995f на скорость, если мяч движется вверх.Работает красиво и выглядит реалистично.Основная проблема в том, что шары никогда не остаются спокойными на земле.Вместо этого они начинают дрожать на земле.Это означает, что есть движение на 1 или 2 пикселя вверх и вниз.

Как я могу предотвратить это, не применяя некоторые "границы", на которых я устанавливаю позицию непосредственно внизу и скорость на ноль?

Мой апплет:

public class BubblePhysicApplet extends PApplet {
    public static int width = 640;
    public static int height = 480;
    long lastTime = -1;
    Bubble[] mBubbles = new Bubble[10];
    Random mRandom = new Random();

    public void setup() {
//      size(width, height, OPENGL);
        size(width, height, P2D);
        for (int i = 0; i < mBubbles.length; i++) {
            mBubbles[i] = new Bubble(mRandom.nextInt(width), mRandom.nextInt(height), 50);
        }
        lastTime = System.currentTimeMillis();
    }

    public void draw() {
        background(0);
        long tmp = System.currentTimeMillis();
        long elapsed = tmp - lastTime;
        for (Bubble bubble : mBubbles) {
            bubble.animate(elapsed);
            bubble.draw(this);
        }
        lastTime = System.currentTimeMillis();
    }
}

Мяч / пузырь:

public class Bubble {
    float mX;
    float mY;
    float mSize;
    float mSpeedX = 0;
    float mSpeedY = 0;

    public Bubble(int x, int y, int size) {
        mX = x;
        mY = y;
        mSize = size;
    }

    public void draw(PApplet applet) {
        applet.stroke(255);
        applet.noFill();
        applet.ellipseMode(PApplet.CENTER);
        applet.ellipse(mX, mY, mSize, mSize);
    }

    public void animate(long elapsed) {
        updateSpeedY(elapsed);
        if (mSpeedX != 0 || mSpeedY != 0) {
            checkBorders();
        }
    }

    private void checkBorders() {
        if (mY > BubblePhysicApplet.height - mSize / 2) {
            mY = 2 * BubblePhysicApplet.height - (mY + mSize);
            mSpeedY = -mSpeedY;
        }
        if (mX > BubblePhysicApplet.width) {
            mX = BubblePhysicApplet.width - (mX - BubblePhysicApplet.width);
            mSpeedX = -mSpeedX;
        }
    }

    private void updateSpeedX() {

    }

    private void updateSpeedY(long elapsed) {
        mSpeedY += (elapsed / 1000f) * 9.81f;
        if (mSpeedY < 0) {
            mSpeedY *= 0.95f;
        }

        mY += mSpeedY;
    }
}

Ответы [ 4 ]

3 голосов
/ 01 июня 2011

Это не только сопротивление воздуха, которое замедляет шар, но и тот факт, что он не идеально эластичен, как предполагает эта линия: mSpeedY = -mSpeedY;

Мяч поглощает энергию, когда он прижимается к полу, прежде чем отскочить назад, поэтому он не отскакивает так высоко. Попробуйте настоящий супер мяч. Кажется, я помню, что отскок на 80% выше. Вы можете попробовать: mSpeedY = - (0,8 * mSpeedY);

2 голосов
/ 02 июня 2011

Точно так же, как вы использовали коэффициент трения для воздуха, вы также можете включить коэффициент трения для контакта с землей и еще более высокие значения, поэтому при каждом контакте он начинает быстро терять энегер и окончательно останавливается

2 голосов
/ 01 июня 2011

Проблема в том, что в updateSpeedY у нас есть mSpeedY += (elapsed / 1000f) * 9.81f;, даже когда происходит столкновение. Это упомянутое столкновение обнаруживается позже в checkBorders, когда скорость переключается mSpeedY = -mSpeedY;. Проблема в том, что если мяч ударяет по полу со скоростью около 0, он отскакивает со скоростью 0 + (elapsed / 1000f) * 9.81f; !!

Вы должны переосмыслить свой код.

2 голосов
/ 01 июня 2011

Вы должны исправить свой метод проверки границ, прочитайте этот ответ Я только что дал полные формулы, необходимые для реалистичного физического моделирования. и это также более реалистично, если вы перемещаете объекты, используя исторический метод (p = v * dt + 1/2 * a dt dt)

...