- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
PAGE6 / NUMPAGES9
9.碰撞1——光滑均匀小球间的碰撞
在引擎中实现了碰撞效果定会使人留下深刻的印象,但这是一个很难的部分,要实现完美的碰撞效果非常不容易,你需要在精度和速度之间找到平衡点。通常碰撞分为两部分:碰撞检测和碰撞反应,碰撞检测是数学几何问题,需要判断是否发生碰撞、在何时何处发生碰撞,很难!网上有很多大部头的书专门讲解碰撞检测背后的数学原理,本人推荐《Real-Time Collision Detection》,在本网站有下载电子书。而碰撞反应主要是物理问题,相对而言简单得多,主要解决碰撞后物体的运动情况。
真实碰撞情况是非常复杂的,本文讨论最简单的情况:两个光滑的、质量分布均匀的小球之间的碰撞。两个小球之间的碰撞只有一个接触点,且相互作用力的方向必为球心连线,而且因为质量分布均匀,质心即球心,即相互作用力的方向必为质心连线,这称之为“中心碰撞”。因为小球光滑,所以无需考虑接触点切线方向的作用力,也就无需计算接触点的坐标,而且没有切线方向的作用力,所以小球也不会发生旋转。
在发布这篇文章之前,我也整理了两篇文章:一篇为 11.3.2 两个轴上的动量守恒,此篇文章介绍了在flash中实现球体非对心碰撞的方法;另一篇为 8.1 线性碰撞,介绍了在silverlight中实现球体对心碰撞的方法。两篇文章的共同点是使用的都是最简单的碰撞检测方法,本文使用的也是这种方法,两篇文章还实现了两球发生完全弹性碰撞时的碰撞反应,而本文要介绍更通用的方法,可以同时处理完全弹性碰撞、完全弹性碰撞和非完全弹性碰撞。
首先我们讨论如何检测两个小球之间是否发生碰撞。
1.碰撞检测
前面已经提及,在这种最简单的情况下,我们无需计算接触点的坐标,只需判断是否发生碰撞,这还是非常简单的,如图1所示:
图1 两个球体之间的碰撞检测
我们首先计算两个球体质心间的距离d和两球半径之和r,然后判断d和r的大小关系得出是否发生接触,但是这只是发生碰撞的必要条件并不充分,还需要检查物体间的法向速度,以判断两物体是靠近中还是远离中,在代码中可以通过点乘相对速度和法线,然后从结果的正负情况进行判断。总而言之,碰撞发生的条件是物体正在接触且接触点朝对方移动,即如上中图所示,即使d=r,若左球相对于右球的速度是向左的,仍然不会发生碰撞。
从上右图我们可以看到还会发生穿透现象,这会使模拟结果很不真实,这时就要使用连续碰撞检测(CCD)将程序倒退一个时间间隔再计算一次,直到没有穿透情况或者正好发生碰撞的情形。这个很难,本文不会介绍也不会现在在代码中实现,在小球速度不大的情况下几乎不会发生穿透现象。
代码实现
理解了原理,下面就讨论一下代码的实现。在World类的Step方法中的Slove方法后面添加以下代码:
public void Step(float dt)
{
[…]
// 对速度进行积分运算, 然后对位置进行积分计算。
Solve(dt);
// 遍历所有Body对象实现碰撞效果
for (int i = 0; i BodyList.Count - 1; i++)
{
Body body1 = BodyList[i];
for (int j = i + 1; j BodyList.Count; j++)
{
Body body2 = BodyList[j];
SolveCollision(body1, body2);
}
}
[…]
}
为什么需要两个循环体的道理可以参见 9.4 多物体碰撞检测策略。
而SolveCollision方法的代码如下:
#region 碰撞检测临时变量
float r; // 两球半径之和
float d2; // 两球球心间距离平方
Vector2 normal; // 碰撞法线矢量
float vrn; // 相对速度的法线分量
#endregion
private void SolveCollision(Body body1, Body body2)
{
// 计算两球的半径之和
r = body1.Radius + body2.Radius;
// 计算两球心间距离的平方
d2 = (body1.Position.X - body2.Position.X) * (body1.Position.X - body2.Position.X) + (body1.Posit
您可能关注的文档
最近下载
- 海南省乡村旅游用地精细化管理问题与对策研究.pdf VIP
- 10kV变压器及高低压柜安装施工方案 - 电气安装工程.docx VIP
- 初中数学八年级上册 三角形 练习题.doc VIP
- GST-QKP04型气体灭火控制器检验报告.pdf VIP
- 专题13 看图写话-2022-2023学年二年级语文上册寒假专项提升(部编).docx VIP
- 北京某养老院居室空间使用调查研究.pdf VIP
- 2023-2024年中国付费自习室行业发展现状与消费趋势调查分析报告.docx VIP
- 2025年九年级数学中考二轮复习专题四边形中的十字架模型与相似三角形综合问题.docx VIP
- 廉洁文化进校园,廉洁在我心.ppt VIP
- 避免潜在的风险.pdf VIP
原创力文档


文档评论(0)