java - 二维质量守恒
问题描述
我有这个程序,球在屏幕上反弹。我希望球能够相互反弹。
所以,我有这个
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;
}
所以这就是我正在使用的弹性碰撞方程,其中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;
}
}
这一切都很好,但它不起作用。球经常粘在一起并永远碰撞,而它应该让球顺利反弹。(如果您需要更多代码,请说出来)
解决方案
您的碰撞处理看起来不对。
让球A
有质量ma
,速度向量VA0
让球B
有质量mb
,速度向量VB0
它们在点碰撞C
要计算碰撞后的速度,我们必须使用能量守恒定律和动量守恒定律
考虑临时轴: - 通过点 和径向连接球中心 与
T
两个球相切C
R
速度上的投影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
推荐阅读
- java - Kafka Streams API-过滤器运算符:“错误:类型参数的数量错误;需要 1”
- c# - 分配谓词变量而不是 lambda 表达式
- django - 具有标记为 pk + fk 的字段的表上的 Django HyperlinkedModelSerializer
- python - scipy dendrogram 不一致地杀死 Spyder 内核
- python - 在 Python 中查找得分最高的单词
- flutter - 如何在 shared_preferences 中创建一个 bool 列表并在那里存储值
- pine-script - 我的策略不执行交易,如何解决?
- angular - 在 Angular 10 上从 node-sass 切换到 sass(dart-sass) 时出错
- c++ - 在编译时获取对象转换为算术类型的地址
- python - Pandas & Datetime - 特定的小时顺序,但更改日期