首页 > 解决方案 > 二维质量守恒

问题描述

我有这个程序,球在屏幕上反弹。我希望球能够相互反弹。

所以,我有这个 boolean intersects(ball b2) {. . .} 方法,它检查 b.intersects 是否与 b2。如果 b.intersects(x) 返回 true,则调用calcDX()and 。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;
}

所以这就是我正在使用的弹性碰撞方程,其中dxdy是 的变化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;
    }
}

这一切都很好,但它不起作用。球经常粘在一起并永远碰撞,而它应该让球顺利反弹。(如果您需要更多代码,请说出来)

标签: javamathphysics

解决方案


您的碰撞处理看起来不对。

让球A有质量ma,速度向量VA0
让球B有质量mb,速度向量VB0
它们在点碰撞C
要计算碰撞后的速度,我们必须使用能量守恒定律和动量守恒定律

考虑临时轴: - 通过点 和径向连接球中心 与
T两个球相切CR

在此处输入图像描述

速度上的投影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


推荐阅读