-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
碰撞求解(二):使用冲量 #35
Comments
thanks |
"若相对速度 > 0,则两对象有分离趋势,若 < 0,则有接近趋势" 这是真的嘛。。。?但若A,B调换位置 再进行相对速度的 <>0比较,似乎两者之一的结果会违反这句。。。 |
我不是很理解你上面关于相对速度的,可能你把他想得太复杂了。 里面VAB * n就是在法线方向上的分离速度的意思。我本人也不过只是一个搬砖码农😂,对于数学物理的知识也忘得差不多了,不过我想这里“相对速度”指的是物理学里面正碰问题的一个概念,和平时的“相对速度”有所区别: 但是我觉得你不必在这个概念上过于深究,因为在真正商用级的物理引擎上(即使是2d),这种碰撞求解方法已经很少被使用了,现在的碰撞求解基本上被抽象成一种不平等约束,用一种叫sequential impulses的方法求解,上面截图的那段代码被这种方法取代了,该方法是box2d创始人提出的,能有更好的堆叠稳定性。 至于法线问题,当然法线是在碰撞检测阶段求出的。你可能没有想明白整个物理引擎的流程😁,碰撞求解是在碰撞检测阶段之后的,碰撞检测筛选出真正发生碰撞的刚体对,并同时求出碰撞法线和碰撞点(box2d中称作碰撞流形),然后这些碰撞对被送往下一阶段即碰撞处理阶段进行求解。这里所说的“碰撞”只是我们现实生活的概念,计算机不知道什么是“碰撞”,所以我们筛选出的刚体只是在空间(或者2d平面)几何意义上相交的物体,这些相交的物体并不是全都需要进行碰撞求解,比如两个刚体存在微小相交但是已有分离趋势,这时就不需作处理。 如果你也对物理引擎有兴趣的话,大家可以多多交流,有人能和我讨论这些内容我也很高兴。 |
看box2d-lite源码时,一直纠结于这个公式是怎么推导出来的。。。 看了这篇文章真是豁然开朗 |
我写了一个2d物理模拟的玩具(https://github.com/THZthz/physics), 但是在物体堆叠时遇到了一个问题: 碰撞约束求解用了累积冲量法, 为了稳定性用了slop和baumgart stabilization |
可以去知乎找一下ACRL这个同学交流一下,我已经很多忘记了 |
上一次讲了基于向量的碰撞求解方法,该方法基本上只适用于无方向的球体间的完全弹性碰撞,灵活性较低。今天介绍一种基于冲量的碰撞求解方法,该方法更加精确,强大,而且能模拟非弹性碰撞。
注意:该文章只涉及一定量数学,要求:
(虽然看着很多公式,但是大部分都是课本现成的物理公式,我们要做的工作只是把这些公式重新组合整理一下而已)
什么是冲量
冲量(impulse)是一个力学上的矢量,记作符号J用于描述物体动量的变化,冲量是一个过程量,比如一个物体t=0时动量5,t=1时动量10,那么该物体在0到1时的冲量为5。
但是我们毕竟不是搞物理的,不需要对某些概念这么深究。我本人简单地将冲量看作为 “ 一股一瞬间改变速度的力 ”,而且该“力”可以作用在物体的任何点上。这就是冲量最大的优点,如果冲量的作用点不过质心,那么物体便会发生旋转。
另外,使用冲量的另一个优点是,冲量可以很容易和力建立联系:
两个小球间的碰撞
现在,我们先将问题简化,考虑两个小球间的碰撞。假设小球为A,B,如图:
其中小球A的质量为massA,碰撞时速度为VA,碰撞后速度为V'A。小球B的质量为massB,碰撞时速度为VB,碰撞后速度为V'B。我们要求的就是改变小球速度的冲量J,下面我们一步步来推导出J。
先从小球的速度入手,我们引入 相对速度(relative velocity) 这个概念:A,B间的相对速度即A的速度减去B的速度,即 公式一 :
其中VAB为A,B的相对速度(对于相对速度的具体理解,可以看下面的评论)。
在碰撞求解中,我们关注的是碰撞法线方向的相对速度,即公式一应该用碰撞法线n表示,也就是说,我们想知道从A到B沿碰撞法向的相对速度,得到公式二:
下一步,我们引入恢复系数(coefficient of restitution)。恢复系数是一个控制碰撞弹性程度的量,用符号e表示,取值范围[0, 1],若e = 1,表示完全弹性碰撞,碰撞后两物体不损失能量;若e = 0,表示完全非弹性碰撞,两物体碰撞后粘在一起,能量和为0。e通常取两物体恢复系数的积的平方根:
现在,根据牛顿恢复定律,有公式三:
该公式表明了碰撞后的速度等于碰撞前的速度乘以恢复系数。
现在我们将公式二和公式三组合一下,得到公式四:
即:
注意,我们要在右边引入一个负号。因为在在牛顿恢复定律中,碰撞后的速度V',实际上是指向碰撞前速度V的相反方向。
目前,我们还没有出现冲量J,别急,下面重点开始了。我们现在要做的就是将冲量J和速度V联系起来。首先看公式五:
该公式描述了碰撞后速度 V' 和碰撞前速度V的关系。又因为冲量J是动量的变化量,有公式六:
现在终于出现了J,为了得到 V' 关于J的表达式,我们将公式五和公式六进行组合,得到公式七:
因为A,B发生碰撞时,A将被推向与B相反的方向,所以:
显然,求 V' 的关键是求出J。将公式四和公式七进行组合,整理,推出公式八:
我们观察这个式子,只有J是未知的,顺理成章地将式子整理一下,将J移到式子左边,其他量移到等式右边,得到J的表达式:
解决了,虽然有点复杂,但是不难理解。将J代入公式七便可以求出小球的碰撞后速度。但是故事还没结束,我们现在的情况只是两个小球间的碰撞,两个小球间的碰撞用向量方法就可解决,搞这么多公式的推导,目的是将碰撞求解抽象到适用于所有情况。
求解复杂的碰撞
有了以上基础,我们来看复杂一点的碰撞求解。例如下面两个矩形的情况:
求解该碰撞的关键在于碰撞点。我们可以视这个碰撞点为两个分别在两个矩形碰撞点位置的小球间的碰撞,那么,对于该碰撞点,便可以转换为两个小球间碰撞的情况。但是问题在于,我们只知道两个矩形的速度,所以要解决问题,需要求出碰撞点分别基于两个矩形的速度:
其中V为线速度,w为角速度,r为碰撞点到矩形质心的距离向量。求出碰撞点速度后再求出J,便可以将J作用在碰撞点上产生摩擦力,加速度和扭矩,使矩形发生位移或旋转。
最后
基于冲量的碰撞求解可以适用于更多情况,而且更加真实,但是并不是完美的。冲量法往往伴随抖动,特别在大量物体堆叠时,抖动会更加明显。碰撞求解不是一个简单的内容,基于冲量的方法仍然不够抽象,接下来有时间我会再介绍一种更高阶的碰撞求解方法。
The text was updated successfully, but these errors were encountered: