- 1、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
碰撞1——光滑均匀小球间的碰撞
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.Position.Y - body2.Position.Y)
文档评论(0)