我想写一个简单的物理模拟,其中半球和质量不同的球在完美弹性和无摩擦的环境中弹跳。我写我自己的代码下面这个资源:http://www.vobarian.com/collisions/2dcollisions2.pdf,我也测试了从这里代码:Ball to Ball Collision - Detection and Handling二维球碰撞问题:没有能量守恒
问题EDITED
与Rick Goldstein和拉尔夫的帮助下,我已经得到了我的代码工作(有一个错字..)。非常感谢你的帮助。不过,我仍然困惑于为什么其他算法不适合我。球沿正确的方向反弹,但系统的总能量永远不会被保存。速度变得越来越快,直到球刚开始在屏幕上的静态位置闪烁。我实际上想在我的程序中使用这些代码,因为它比我写的更简洁。
这里是我写的功能算法(虽然我没有从其他来源获得第一位)。它在气泡类别:
public void resolveCollision(Bubble b)
{
// get the minimum translation distance
Vector2 delta = (position.subtract(b.position));
float d = delta.getMagnitude();
// minimum translation distance to push balls apart after intersecting
Vector2 mtd = delta.multiply(((getRadius() + b.getRadius())-d)/d);
// resolve intersection --
// inverse mass quantities
float im1 = 1/getMass();
float im2 = 1/b.getMass();
// push-pull them apart based off their mass
position = position.add(mtd.multiply(im1/(im1 + im2)));
b.position = b.position.subtract(mtd.multiply(im2/(im1 + im2)));
//get the unit normal and unit tanget vectors
Vector2 uN = b.position.subtract(this.position).normalize();
Vector2 uT = new Vector2(-uN.Y, uN.X);
//project ball 1 & 2 's velocities onto the collision axis
float v1n = uN.dot(this.velocity);
float v1t = uT.dot(this.velocity);
float v2n = uN.dot(b.velocity);
float v2t = uT.dot(b.velocity);
//calculate the post collision normal velocities (tangent velocities don't change)
float v1nPost = (v1n*(this.mass-b.mass) + 2*b.mass*v2n)/(this.mass+b.mass);
float v2nPost = (v2n*(b.mass-this.mass) + 2*this.mass*v1n)/(this.mass+b.mass);
//convert scalar velocities to vectors
Vector2 postV1N = uN.multiply(v1nPost);
Vector2 postV1T = uT.multiply(v1t);
Vector2 postV2N = uN.multiply(v2nPost);
Vector2 postV2T = uT.multiply(v2t);
//change the balls velocities
this.velocity = postV1N.add(postV1T);
b.velocity = postV2N.add(postV2T);
}
这里是行不通
public void resolveCollision(Bubble b)
{
// get the minimum translation distance
Vector2 delta = (position.subtract(b.position));
float d = delta.getMagnitude();
// minimum translation distance to push balls apart after intersecting
Vector2 mtd = delta.multiply(((getRadius() + b.getRadius())-d)/d);
// resolve intersection --
// inverse mass quantities
float im1 = 1/getMass();
float im2 = 1/b.getMass();
// push-pull them apart based off their mass
position = position.add(mtd.multiply(im1/(im1 + im2)));
b.position = b.position.subtract(mtd.multiply(im2/(im1 + im2)));
// impact speed
Vector2 v = (this.velocity.subtract(b.velocity));
float vn = v.dot(mtd.normalize());
// sphere intersecting but moving away from each other already
if (vn > 0.0f) return;
// collision impulse (1f is the coefficient of restitution)
float i = (-(1.0f + 1f) * vn)/(im1 + im2);
Vector2 impulse = mtd.multiply(i);
// change in momentum
this.velocity = this.velocity.add(impulse.multiply(im1));
b.velocity = b.velocity.subtract(impulse.multiply(im2));
}
我们,如果你发现任何我知道的一个。谢谢
雅这是错字...我一直在电脑前呆了太久,我多次查了一遍数学。谢谢。看看我的编辑虽然,我真的想让其他算法的工作和它绝对不是同一个问题 – Cbas 2011-02-16 02:51:26
至于你的第二点,我不检查,看看我是否已经通过气泡解决了我的循环中的碰撞,但我不认为这很重要,因为我在这个resolveCollision方法中做的第一件事是将它们拉开。当循环在碰撞中找到另一个球时,它不会再发生碰撞并且不会再次调用这个方法 – Cbas 2011-02-16 02:56:36