根据这些规律可以得到下列方程组:
解该方程组,得到下面的公式:
把这二个公式相减,可以得到:
即:
我们也经常利用这个公式简化运算
基本的动量守恒演示:
先给ball类添加一个质量"属性"
一维单轴刚体碰撞测试:
二维坐标上的刚体碰撞:
先来看这张图,红球a以Va速度运动,蓝球b以Vb速度运动,二球的连线正好与x轴平行(即:水平对心碰撞),碰撞的过程可以理解为二球水平速度分量Vax,Vbx应用运量守恒与能力守恒的结果(y轴方向的速度不受影响!)
但很多情况下,二球的连线并非总是与坐标轴平行,比如下面这样:
思路:仍然利用坐标旋转,先将二个球反向旋转到连线水平位置,然后按常规方式处理,完事后再旋转回来。
粘连问题:
反复运行上面这段动画,偶尔可能会发现二个球最终粘在一起,无法分开了,造成这种原因的情况很多,下面的示意图分析了可能的形成原因之一
解决思路:找出重叠部分,然后把二个小球同时反向移动适当距离,让二个球分开即可
先来一段测试代码:验证一下是否有效
水平拖动小球故意让它们重叠,然后点击“分开”按钮测试一下,ok,管用了!
再回过头来解决运量守恒中的粘连问题:
只要把EnterFrameHandler中的
1
2
3
4
5
|
//相对位置处理
xA+=vxAFinal;
xB+=vxBFinal;
|
换成:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
//相对位置处理(同时要防止粘连)
//xA+=vxAFinal;
//xB+=vxBFinal;
var
sumRadius = ballA.radius + ballB.radius;
var
overlap:
Number
=sumRadius-Math.abs(xA-xB);
//计算重叠部分
//trace(overlap);
//计算每个球所占重叠部分中的比例
var
aRadio:
Number
= ballA.radius/sumRadius;
var
bRadio:
Number
= ballB.radius/sumRadius;
//分离判断
if
(overlap>
0
){
if
(xA>xB){
xA += overlap*aRadio;
xB -= overlap*bRadio;
}
else
{
xA -= overlap*aRadio;
xB += overlap*bRadio;
}
}
|
最后老规矩:来一个群魔乱舞,把一堆球放在一块儿乱撞
注:这段代码做了优化,把一些公用的部分提取出来封装成function了,同时对于粘连问题的解决,采用了更一种算法
后记:弄懂了本文中的这些玩意儿有啥用呢?让我想想,或许...公司需要开发一款桌面台球游戏时,这东西就能派上用场吧.