碰撞1光滑均匀小球间的碰撞Word格式文档下载.docx

上传人:b****6 文档编号:18360564 上传时间:2022-12-15 格式:DOCX 页数:11 大小:50.39KB
下载 相关 举报
碰撞1光滑均匀小球间的碰撞Word格式文档下载.docx_第1页
第1页 / 共11页
碰撞1光滑均匀小球间的碰撞Word格式文档下载.docx_第2页
第2页 / 共11页
碰撞1光滑均匀小球间的碰撞Word格式文档下载.docx_第3页
第3页 / 共11页
碰撞1光滑均匀小球间的碰撞Word格式文档下载.docx_第4页
第4页 / 共11页
碰撞1光滑均匀小球间的碰撞Word格式文档下载.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

碰撞1光滑均匀小球间的碰撞Word格式文档下载.docx

《碰撞1光滑均匀小球间的碰撞Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《碰撞1光滑均匀小球间的碰撞Word格式文档下载.docx(11页珍藏版)》请在冰豆网上搜索。

碰撞1光滑均匀小球间的碰撞Word格式文档下载.docx

这个很难,本文不会介绍也不会现在在代码中实现,在小球速度不大的情况下几乎不会发生穿透现象。

代码实现

理解了原理,下面就讨论一下代码的实现。

在World类的Step方法中的Slove方法后面添加以下代码:

publicvoidStep(floatdt)

{

[…]

//对速度进行积分运算,然后对位置进行积分计算。

Solve(dt);

//遍历所有Body对象实现碰撞效果

for(inti=0;

i<

BodyList.Count-1;

i++)

Bodybody1=BodyList[i];

for(intj=i+1;

j<

BodyList.Count;

j++)

Bodybody2=BodyList[j];

SolveCollision(body1,body2);

}

为什么需要两个循环体的道理可以参见9.4多物体碰撞检测策略。

而SolveCollision方法的代码如下:

#region碰撞检测临时变量

floatr;

//两球半径之和

floatd2;

//两球球心间距离平方

Vector2normal;

//碰撞法线矢量

floatvrn;

//相对速度的法线分量

#endregion

privatevoidSolveCollision(Bodybody1,Bodybody2)

//计算两球的半径之和

r=body1.Radius+body2.Radius;

//计算两球心间距离的平方

2/9

d2=(body1.Position.X-body2.Position.X)*(body1.Position.X-body2.Position.X)+

(body1.Position.Y-body2.Position.Y)*

osition.Y-body2.Position.Y);

//通过比较d平方和r平方判断是否发生碰撞。

这里没有使用d.Length()和r比较,因

为计算d的大小涉及开方操作比较耗费资源。

boolisTouching=d2<

=r*r?

true:

false;

//计算球1质心指向球2质心的矢量,即法线矢量。

normal=body2.Sweep.C.X-body1.Sweep.C.X的内联写法

normal.X=body2.Sweep.C.X-body1.Sweep.C.X;

normal.Y=body2.Sweep.C.Y-body1.Sweep.C.Y;

//以下三行代码对法线normal进行归一化,即法线的单位向量。

normal.Normalize()的

内联写法。

floatfactor=1f/(float)Math.Sqrt(normal.X*normal.X+normal.Y*normal.Y);

normal.X*=factor;

normal.Y*=factor;

//计算相对速度的法线分量。

Vector2.Dot(body1.LinearVelocityInternal-

body2.LinearVelocityInternal,d)的内联写法。

//数学知识告诉我们:

这个值为正表示相对法线速度方向与法线方向的夹角小于90度,

即两球正在相互靠近

vrn=normal.X*(body1.LinearVelocityInternal.X-body2.LinearVelocityInternal.X)+

normal.Y*(body1.LinearVelocityInternal.Y-

body2.LinearVelocityInternal.Y);

//若d小于等于r且正在相互靠近则说明发生碰撞

if(isTouching&

&

vrn>

0)

//碰撞反应代码,在后面实现

2.碰撞反应

当上述碰撞检测过程检测到发生碰撞后,我们就要着手处理碰撞后物体的运动情况,这

个问题主要是根据物理学中的动量守恒定律加以解决的。

2.1动量守恒定律

如果一个系统不受外力或所受外力的矢量和为零,那么这个系统的总动量保持不变,

这个结论叫做动量守恒定律。

动量守恒定律是自然界中最重要最普遍的守恒定律之一,它既

适用于宏观物体,也适用于微观粒子;

既适用于低速运动物体,也适用于高速运动物体,它

是一个实验规律,也可用牛顿第三定律和动量定理推导出来。

3/9

动量守恒定律和能量守恒定律以及角动量守恒定律一起成为现代物理学中的三大基本守恒定律。

最初它们是牛顿定律的推论,但后来发现它们的适用范围远远广于牛顿定律,是比牛顿定律更基础的物理规律,是时空性质的反映。

其中,动量守恒定律由空间平移不变性推出,能量守恒定律由时间平移不变性推出,而角动量守恒定律则由空间的旋转对称性推出。

在任何短暂的碰撞过程中,与相碰物体间巨大的内力相比,外力的冲量是微不足道的。

因而总可认为,碰撞过程中系统的总动量是守恒的。

根据动量守恒定律,已知碰撞前两物体的初始条件,就可以求出碰撞后两物体的运动情况。

在无摩擦力的碰撞中,撞击的作用线垂直于碰撞的接触面。

当速度沿作用线时,这种碰撞称为“直接碰撞”(directimpact);

当作用线通过物体质心时,这种碰撞称为“中心碰撞”(centralimpact)。

质量分布均匀的球体遭受的撞击都是中心碰撞,而直接中心碰撞发生在作用线通过碰撞物体质心且速度沿着作用线时,对应的就是一维直线上的碰撞。

当物体的速度不沿着作用线时,这种撞击称为“倾斜碰撞”(obliqueimpact),在这种情况中你可以利用分解速度来分析倾斜碰撞,只有平行于作用线的分量才与碰撞有关,而垂直于作用线的分量则无,对应的是二维平面上的碰撞。

图2显示了这些碰撞。

图2撞击的种类

以上公式对应的都是一维直线上的碰撞,如果处理的二维平面,速度应该代矢量形式。

例如如图3所示有两个质量分布均匀的球体,一个质量m,1kg,初速度v,1m/s向110右,另一个质量为m,2kg,初速v,2m/s向左,从图中可以看出这属于前面提到的直接220

中心碰撞,碰撞只发生在球心连线上。

那么如何计算它们发生碰撞后的速度v和v,12

图3两个小球的直接中心碰撞

4/9

根据能量损耗的情况主要分为三种情况。

2.1.1完全非弹性碰撞

若在碰撞过程中相对动能完全耗散掉,碰撞后两物体不再分离,这种情况称之为完全非弹性碰撞。

根据动量守恒定律(设向右为正):

mv,mv,(m,m)v共11022012

v,mmv1×

1,2×

(,2)110220v,,m/s,,1m/s共m,m1,212

即碰撞后两者黏在一起以1m/s的速度向左运动。

2.1.2完全弹性碰撞

若在碰撞过程中没有能量损耗,这种情况称之为完全弹性碰撞。

需要动量守恒定律和动能守恒联立才能解出方程:

mv,mv,mv,mv1102201122

11112222mv,mv,mv,mv11022011222222

以上两式联立解得:

(m,m)v,2mv(1,2)×

(,2)1210220v,,m/s,,3m/s1m,m1,212

m)v,2mv(m(2,1)×

(,2),2×

12120110v,,m/s,02m,m1,212

即m小球以3m/s的速度反弹,m小球恰静止。

12

2.1.3非完全弹性碰撞

若碰撞过程中相对动能只耗散掉一部分,这种情况称之为非完全弹性碰撞,要解出方程,还需要一个由两碰撞物体的材质、结构、几何形状等决定的物理量:

恢复系数e(coefficient

v,v12ofrestitution),定义为,,这个恢复系数可由实验测出,范围为[0,1],当e,0时v,v1020

即完全非弹性碰撞,e,1时为完全弹性碰撞。

下表为几种材料的恢复系数。

材料玻璃和玻璃铝和铝铁与铝钢与软木e值0.930.200.120.55

有了恢复系数,则碰撞后的速度v和v可由以下公式计算,若取e,0.5,则:

em)v,(1,e)mv(m(1,1)×

1,(1,0.5)×

21210220v,,m/s,,2m/s1m,m1,212

(m,em)v,(1,e)mv(2,0.5)×

2,(1,0.5)×

12120110v,,m/s,,0.5m/s2m,m1,212

即碰撞后m和m小球都向左运动。

5/9

上述公式可以同时处理以上三种碰撞情况,当e,0退化为完全非弹性碰撞,e,1退化为完全弹性碰撞。

2.2线性冲量

如果要解决球体的碰撞反应,使用上述的动量守恒定律和恢复系数就够用了,但是如果碰撞物体是不规则的的刚体,则需要用到更全面的方法。

这种方法要计算碰撞物体间的线性冲量(本文不涉及角冲量的计算),然后将此线性冲量作用在物体上改变其速度。

施加线性冲量的代码前面的文章已经实现了,只需通过物理公式的推导线性冲量的公式,此公式的推导过程较复杂,就不列出了,可参见《游戏开发物理学》第101-102页。

我们只需知道结论,碰撞后施加在两物体上的冲量I矢量为:

v(1,e)rI,11,mm12

式中v为第一个刚体(注意:

这个方法不仅可以用在小球的情况下,也可以用在不规r

则的刚体上)相对于第二个刚体的速度矢量。

有了作用在物体上的冲量,则可以用以下公式计算两个刚体碰撞之后的速度:

Inv,v,110m1

因为碰撞时作用在两个物体上的冲量大小相等,方向相反且在一直线上,所以:

Inv,v,220m2

公式中的I为法线方向的冲量矢量。

n

下面我们根据这个通用方法将上面的非完全弹性碰撞的例子再做一遍。

这个例子是一维直线上的碰撞,因此上述矢量式可以简化为标量式。

首先计算相对速度

v,v,v,1,(,2),3m/sr1020

然后计算冲量:

I,,3×

(1,0.5)/(1,0.5),,3N?

s

两刚体的最后的速度为:

v,1,,3/1,,2m/s1

v,,2,3/2,,0.5m/s2

结果完全相同~但这种方法更为通用。

2.3倾斜碰撞

前面讨论的例子只处理了一维直线上的碰撞情况,下面我们将讨论如果处理倾斜碰撞,如下图4所示,质量为2kg,半径为2m/s的小球1以5m/s的速度向上运动,质量为3kg,半径为3m的小球2以5m/s的速度向左运动,如何求出这种情况下的两个小球末速度,

6/9

图4两个小球的倾斜碰撞

首先我们需要求出碰撞的法线方向,这个方向就是小球1球心指向小球2球心的方向,

图4用黄色箭头d表示,d的矢量表达式为d,4i,3(ji和j表示x与y方向上的单位矢量),

然后对它归一化,获取单位法线向量(用红色箭头表示)n,0.8i,0.6j。

接着获取v和v的法线分量v,3m/s和v,,4m/s,做好准备工作后,就可以按102010n20n

前面提到的公式计算法线方向的碰撞结果了,设e,1,则:

v,v,v,7m/srn10n20n

I,,7×

(1,1)/(0.5,1/3),,16.8N?

sn

v,3,16.8/2,,5.4m/s1n

v,,4,16.8/3,1.6m/s2n

而小球在切线方向的速度v和v保持不变,因此小球的最终速度大小为:

10t20t

22v,v,v,6.72m/s11n10t22v,v,v,3.4m/s22n20t

速度方向也可以求出,不再赘述。

2.4代码实现

理解了上述原理,就可以编写碰撞反应代码了,完整代码如下,其中红色的代码为相对

于上一次多出的代码:

7/9

floatnormalImpulse;

//法线方向的冲量

floatnormalMass;

//计算法线冲量时用到的等效质量

floatrestitution;

//恢复系数

privatevoidSolveCollision(Bodybody1,Bodybody2){

//碰撞时受到的冲量的公式为:

//I,,vr(1+e)/(1/m1,1/m2)

//可将1/(1/m1,1/m2)看成一个等效质量normalMass

8/9

normalMass=1.0f/(body1.InvMass+body2.InvMass);

//恢复系数取为两个球体恢复系数的平均值

restitution=(body1.Restitution+body2.Restitution)/2;

//更据公式计算法线冲量

normalImpulse=-normalMass*vrn*(1+restitution);

//分别求出x,y方向上的冲量分量

floatIx=normalImpulse*normal.X;

floatIy=normalImpulse*normal.Y;

//在两个刚体上施加冲量

body1.LinearVelocityInternal.X+=body1.InvMass*Ix;

body1.LinearVelocityInternal.Y+=body1.InvMass*Iy;

body2.LinearVelocityInternal.X-=body2.InvMass*Ix;

body2.LinearVelocityInternal.Y-=body2.InvMass*Iy;

其中恢复系数Restitution是在Body类中新添的一个属性。

但是从物理上来说这是不正

确的,因为恢复系数是碰撞的两个物体共同的属性,讨论一个物体的恢复系数是无意义的。

但在计算机代码上只能这样做,我进行的操作是取两者的平均值,你也可以取个较大值或取

个较小值。

其余原理在源代码的注释中已经写得很清楚了。

Silverlight示例

示例的代码就不贴了,自己看源代码吧。

在屏幕上添加了15个小球,随机赋予半径、初速和恢复系数。

如果每个小球的恢复系

数为1的话,则系统总能量守恒,小球会永远不停地动下去,而这个例子中小球最终会停下

来。

9/9

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1