2d球没有正确碰撞

我只是想编写一个漂亮的物理游戏。

球碰撞看起来不错,但如果球碰撞得太慢,它们会互相“粘”。 我不知道他们为什么这样做。

这是我的碰撞function:

private void checkForCollision(ArrayList balls) { for (int i = 0; i < balls.size(); i++) { Ball ball = balls.get(i); if (ball != this && ball.intersects(this)) { this.collide(ball, false); } } } public boolean intersects(Ball b) { double dx = Math.abs(b.posX - posX); double dy = Math.abs(b.posY - posY); double d = Math.sqrt(dx * dx + dy * dy); return d <= (radius + b.radius); } private void collide(Ball ball, boolean b) { double m1 = this.radius; double m2 = ball.radius; double v1 = this.motionX; double v2 = ball.motionX; double vx = (m1 - m2) * v1 / (m1 + m2) + 2 * m2 * v2 / (m1 + m2); v1 = this.motionY; v2 = ball.motionY; double vy = (m1 - m2) * v1 / (m1 + m2) + 2 * m2 * v2 / (m1 + m2); if (!b) ball.collide(this, true); System.out.println(vx + " " + vy); motionX = vx * BOUNCEOBJECT; motionY = vy * BOUNCEOBJECT; } 

但是当它们以低速碰撞时会发生这种情况: 在此处输入图像描述

你有什么想法吗?

编辑:

Alnitak的更新工作非常好……但仍存在一个问题……如果我像这样添加引力:

 public void physic() { motionY += GRAVITY; // <= this part (GRAVITY is set to 0.3D) checkForCollision(screen.balls); keyMove(); bounceWalls(); posX += motionX; posY += motionY; } 

他们仍然相互移动。 我认为这是增加引力的错误方法,或者不是吗?

而且我认为碰撞公式我做错了,因为它们不合适:

落球

然后他们慢慢沉入地下。

编辑:找到一个惊人的教程: http //www.ntu.edu.sg/home/ehchua/programming/java/J8a_GameIntro-BouncingBalls.html

 (m1 - m2) * v1 / (m1 + m2) + 2 * m2 * v2 / (m1 + m2); 

这有一个整数值2.请将其设为2.0f或2.0d然后检查出来。 它必须是小速度的问题。 因此,整数常量自动编码乘以双倍。

如果这不起作用,那么Alnitak的回答将会有所帮助。

如果你需要真正好的物理,你应该使用然后将其转换为速度然后将其转换为位移 。 看看Runge KuttaEuler Integration等集成商技术

 Force-->acceleration-->velocity-->displacement 

如果发生碰撞,只需更新力,然后剩下的就会流动。

—-> http://codeflow.org/entries/2010/aug/28/integration-by-example-euler-vs-verlet-vs-runge-kutta/ <-----

http://www.forums.evilmana.com/game-programming-theory/euler-vs-verlet-vs-rk4-physics/

http://www.newagepublishers.com/samplechapter/001579.pdf

http://cwx.prenhall.com/bookbind/pubbooks/walker2/

Verlet积分Runge-Kutta-4Euler Integration之间的一个点,最好是分子动力学(如果你省略电场和键,这是弹跳球的一个很好的例子)

这是一个常见的问题,因为有时弹跳球的delta-v不足以将其从碰撞区带回。

因此碰撞程序再次反转方向,将其带回到另一个球内,无限制。

您应该在球的位置添加足够的偏移(在碰撞力的方向上),以确保新计算的位置不再发生碰撞。

或者,在添加新motion值后检查球是否发生碰撞:

 public boolean intersects(Ball b) { double dx = b.posX - (posX + motionX); // no need for Math.abs() double dy = b.posY - (posY - motionY); double d = dx * dx + dy * dy; // no need for Math.sqrt() return d < (radius + b.radius) * (radius + b.radius); } 

但是你也应该将ball.intersects(this)改为ball.intersects(this) intersects(ball)

它们可能看起来过早地碰撞,但是在快速移动的球上它可能不会被看到。

刚刚找到一个惊人的教程: http ://www.ntu.edu.sg/home/ehchua/programming/java/J8a_GameIntro-BouncingBalls.html