不同球质量的真实球碰撞 - 小球阻止大球
Realistic ball collision with different ball mass - small balls stop the large ones
tl;dr demo with editor of the bounce function
单击以将新球添加到该区域
有一个 question with over 200 votes on this topic 的最佳答案得分不到一半。我注意到这一点,因为答案通常比问题更重要。
我尝试将建议的代码转换为 javascript。我的 球 小行星具有以下属性:
vx
, vy
- x 轴和 y 轴的速度
x
和 y
位置
mass
以公斤为单位,如果重要的话
因此我的代码如下:
function bounce(objectA, objectB) {
/** objectA and objectB have following properties:
* vx, vy - speed in x and y direction
* x, y - position
* mass - masss
* radius - diameter, calculated from mass
* using average rock density according to wikipedia
***/
// Colision point as seen from B's perspective
var collision = [objectA.x-objectB.x, objectA.y-objectB.y];
var distance = Math.sqrt(collision[0]*collision[0] + collision[1]*collision[1]);
collision[0] /= distance;
collision[1] /= distance;
var aci = objectA.vx* collision[0] + objectA.vy* collision[1];
var bci = objectB.vx* collision[0] + objectB.vy*collision[1];
var totalMass = objectA.mass + objectB.mass;
// This is what I had to add since the original answer doesn't account for mass
var acf = bci * objectB.mass/totalMass;
var bcf = aci * objectA.mass/totalMass;
// I put velocities in arrays in case I wanted to apply more changes
// I mean I need to apply some changes, but I don't know what changes exactly
// to make this crap of code work
var v1 = [(acf-aci) * collision[0], (acf-aci) * collision[1]];
var v2 = [(bcf-bci) * collision[0], (bcf-bci) * collision[1]];
// Addition sure works better than assignment, but I encourage to try it for
// the lulz
objectA.vx += v1[0];
objectA.vy += v1[1];
objectB.vx += v2[0];
objectB.vy += v2[1];
}
现在在我的场景中,我观察到奇怪的行为。如果大球撞到小球,小球飞快地飞走,而大球则完全停止。足够大的球应该在不减速的情况下将小球推开。
情况:
发生这种情况:
无论您使用什么尺寸,这种情况永远不会发生:
我认为这是我在两个球之间分配速度的方式造成的。但是如何确定变化呢?
我明白这个问题仅靠看代码是很难回答的。不幸的是,上下文不适合 jsfiddle 中的 SSCCE。因此,我费了一番功夫,创建了online demo on github pages,这里可以直接编辑上面的功能,立即生效。我会尽最大努力确保保留演示以供进一步参考。
继续阅读 elastic collisions。您的方程式缺少重要因素,例如质量差异和碰撞角(因为您在二维空间中工作)。
对于一维碰撞,您需要实现以下等式(来自维基百科页面),其中 u1
和 u2
是碰撞前每个物体的速度,v1
/v2
是之后的速度。
您可以通过检查系统的总动量和动能在整个碰撞过程中保持不变来验证您的结果。
二维方程也在那篇文章中,但涉及更多,所以我不会在这里复制它们(我只是粘贴整篇文章)。重要的是,它们需要使用三角函数(sin
、cos
)和点积,而这些在您当前的实现中是不存在的。
tl;dr demo with editor of the bounce function
单击以将新球添加到该区域
有一个 question with over 200 votes on this topic 的最佳答案得分不到一半。我注意到这一点,因为答案通常比问题更重要。
我尝试将建议的代码转换为 javascript。我的 球 小行星具有以下属性:
vx
,vy
- x 轴和 y 轴的速度x
和y
位置mass
以公斤为单位,如果重要的话
因此我的代码如下:
function bounce(objectA, objectB) {
/** objectA and objectB have following properties:
* vx, vy - speed in x and y direction
* x, y - position
* mass - masss
* radius - diameter, calculated from mass
* using average rock density according to wikipedia
***/
// Colision point as seen from B's perspective
var collision = [objectA.x-objectB.x, objectA.y-objectB.y];
var distance = Math.sqrt(collision[0]*collision[0] + collision[1]*collision[1]);
collision[0] /= distance;
collision[1] /= distance;
var aci = objectA.vx* collision[0] + objectA.vy* collision[1];
var bci = objectB.vx* collision[0] + objectB.vy*collision[1];
var totalMass = objectA.mass + objectB.mass;
// This is what I had to add since the original answer doesn't account for mass
var acf = bci * objectB.mass/totalMass;
var bcf = aci * objectA.mass/totalMass;
// I put velocities in arrays in case I wanted to apply more changes
// I mean I need to apply some changes, but I don't know what changes exactly
// to make this crap of code work
var v1 = [(acf-aci) * collision[0], (acf-aci) * collision[1]];
var v2 = [(bcf-bci) * collision[0], (bcf-bci) * collision[1]];
// Addition sure works better than assignment, but I encourage to try it for
// the lulz
objectA.vx += v1[0];
objectA.vy += v1[1];
objectB.vx += v2[0];
objectB.vy += v2[1];
}
现在在我的场景中,我观察到奇怪的行为。如果大球撞到小球,小球飞快地飞走,而大球则完全停止。足够大的球应该在不减速的情况下将小球推开。
情况:
发生这种情况:
无论您使用什么尺寸,这种情况永远不会发生:
我认为这是我在两个球之间分配速度的方式造成的。但是如何确定变化呢?
我明白这个问题仅靠看代码是很难回答的。不幸的是,上下文不适合 jsfiddle 中的 SSCCE。因此,我费了一番功夫,创建了online demo on github pages,这里可以直接编辑上面的功能,立即生效。我会尽最大努力确保保留演示以供进一步参考。
继续阅读 elastic collisions。您的方程式缺少重要因素,例如质量差异和碰撞角(因为您在二维空间中工作)。
对于一维碰撞,您需要实现以下等式(来自维基百科页面),其中 u1
和 u2
是碰撞前每个物体的速度,v1
/v2
是之后的速度。
您可以通过检查系统的总动量和动能在整个碰撞过程中保持不变来验证您的结果。
二维方程也在那篇文章中,但涉及更多,所以我不会在这里复制它们(我只是粘贴整篇文章)。重要的是,它们需要使用三角函数(sin
、cos
)和点积,而这些在您当前的实现中是不存在的。