基于冲量的刚体碰撞运动
原作者:
Katsuaki Kawachi ,Hiromasa Suzuki, Fumihiko Kimura,J¨org Sauer,Elmar,Sch omer
整理,编写代码: ZH1110
我们在模拟中通常会遇到三种接触情况:
1.双侧的强制约束(Bilateral Constraints),约束始终保持,以前所研究过的是其中的一种方法.
2.瞬间非持久接触(non-permanent permanent contacts),如锻铁、打桩等,可称为碰撞。其特点是在很短的时间间隔内物体的速度发生突然的变化,所以我们很难直接计算其受力大小,而要通过碰撞前后速度变化的规律入手。在这一章我们主要讨论基于冲量的两刚体碰撞运动。
3.持久接触(permanent contacts)第一种的特殊情况.运动着的物体,突然对其施加约束,物体的速度也会发生突变。但在一定条件下约束会消失.他是基于约束(Constraint-based)的
图1,接触的三种情况
本节将根据动力学的基本原理对碰撞现象进行描述,讨论其的基本规律,及计算。
基本的冲突碰撞
一.简化模型的基本的假设:
1.刚体是坚硬的不会因碰撞发生变形
2.对象是多边形
3.摩擦计算基于库仑定律
我们使用下面的符号来表示用到的物理量:(粗体-矢量,常规-标量)
ma ,mb
|
对象a,b的质量 |
Ia ,Ib
|
惯性矩, 转动惯量 |
uA ,uB
|
在碰撞前物体A,B中心线速度矢量 |
uA',uB'
|
在碰撞以后物体A,B中心线速度矢量 |
ωA ,ωB
|
碰撞前角速度 |
ωA',ωB'
|
碰撞以后角速度 |
P
|
碰撞点 |
vA ,vB
|
在碰撞前撞击点线速度矢量 |
vA',vB'
|
在碰撞以后撞击点线速度矢量 |
GA ,GB
|
重心坐标 |
rA ,rB
|
重心坐标到碰撞点的矢量 |
Pn
|
碰撞的垂直冲量(Pn=Pn*N) |
ra,rb在碰撞过程中不会改变,因为假设刚体在碰撞过程中不发生位置的变化.
写成如下形式:
⑴
Va为碰撞前刚体A在碰撞点P的速度,Va'为碰撞后刚体A在碰撞点P的速度
角速度与线速度变化遵守冲量定理:
⑵
通过⑴,⑵方程式,我们合并为:
⑶
这个方程除了vA'还有Pn是未知量.注意:后面代码我们是把N提到括号外面,计算冲量Pn的矢量数值的。
将后面已知部分化简为一常量矢量CA, 类似的我们可得B物体的简写方程式:
⑷
B物体的N是相反的,即-N.
利用Va,Vb的的相对速度Vn,可以判断是否发生碰撞,如果Vn < 0意味着发生碰撞,如果Vn = 0意味着发生接触,如果Vn > 0意味着发生分离.Vn的定义如下:
⑸
和并后个方程式可得碰撞以后的相对速度V'n
⑹
如果有n个碰撞点这个方程可扩展为:
⑺ (本章暂不讨论多个碰撞点同时发生的情况)
为了计算P,定义一个恢复因数ξ,(牛顿认为碰撞前后相对速度的比为此常数,且该常数与碰撞物体的材料性质有关,与物体的形状、大小与碰撞前的速度无关。)这个重要公式为:
⑻
它表明:如果发生碰撞( Pn<>0 ),那么方程就变为
Vn'=-ξVn ⑼
计算刚体碰撞运动的一般过程:
1.利用碰撞检测技术检测发生碰撞的二刚体及碰撞点P,碰撞的垂直方向N
2.使用公式⑸计算相对速度Vn.如果Vn>=0,表示两物体处于分离,不再进行计算退出. 使用公式⑼计算相对速度Vn'.
3.使用公式⑶,⑷计算常量Ca,Cb(如果是地面,可将其看做一个质量很大的刚体,也可单独处理)
4.使用公式⑹计算碰撞的垂直冲量Pn
5.将Pn代入⑵即可得到二刚体碰撞后的状态.
代码如下:
Private Sub process_collision(Boxa As box, Boxb As box, collpos As D3DVECTOR, colN As D3DVECTOR, extra As Single) '开始正冲量的计算 Dim cl As collision cl.N = colN ' 碰撞的垂直方向 cl.Ra = Subtract(collpos, Boxa.pos)'重心坐标到碰撞点的矢量 cl.Rb = Subtract(collpos, Boxb.pos) cl.Va = Add(cross(Boxa.Vang, cl.Ra), Boxa.v) ' v'= v +ω×R cl.Vb = Add(cross(Boxb.Vang, cl.Rb), Boxb.v) cl.Vn = Dot(cl.N, cl.Va) - Dot(cl.N, cl.Vb) - 0.2 * extra '相对垂直速度, 另外副加微小冲量
cl.Vn2 = -0.4 * cl.Vn '垂直相对速度(碰撞后),0.4是恢复因数
If cl.Vn >= 0 Then Exit Sub
'计算Ca Ca = 1/m+((Ra×N)/Iz×Ra)N Cb = 1/m+((Rb×N)/Iz×Rb)N cl.Ca = 1 / Boxa.m + Dot(cross(VScale(cross(cl.Ra, cl.N), 1 / Boxa.Iz), cl.Ra), cl.N) cl.Cb = 1 / Boxb.m + Dot(cross(VScale(cross(cl.Rb, cl.N), 1 / Boxb.Iz), cl.Rb), cl.N)
D3DXVec3Scale cl.Pn, cl.N, ((cl.Vn2 - cl.Vn) / (cl.Ca + cl.Cb)) applyimpulse Boxa, cl.Pn, collpos '应用正冲量 applyimpulse Boxb, VScale(cl.Pn, -1), collpos ... End Sub
摩擦冲量
既然碰撞的正方向可以应用冲量方程,那么在与之相垂直的方向(摩擦力方向)也可用此方程,只是后面的判断方法不同.
如果2个对象接触并滑行,摩擦力会一直作用于滑行点上,同样的如果发生碰撞,正冲量与摩擦冲量也同时工作,我们描述摩擦产生的冲量为摩擦冲量.
如果摩擦力做工,相切的摩擦冲量将要运做,(t是单位矢量相切于碰撞的边,它的方向可通过P的的速度判断.)如图:
这种情况,相切的速度与冲量关系可以写成类似于方程⑶的形式,:
⑼
在碰撞期间的摩擦力
在无摩擦的系统下,正接触力fn(t)在[t0,t1]段间持续的作用于2刚体上,因此P点的正冲量为:
⑽
现在假设在P点的速度在碰撞开始和期间始终不为0,等量摩擦力ft(t)持续的作用,P点的摩擦量冲为:
(11)
假设在P点碰撞期速度变成了0,摩擦力顶多保持在静摩擦状态,摩擦量冲被限制在:
(12)
从上面的推断我们可以推断摩擦冲量的计算过程:
1.根据式⑼与式(11)的摩擦冲量都计算出来
2.如果前者小于后者表示动摩擦力不能一直维持到碰撞结束,实际摩擦冲量为前者,反之亦然.
'开始摩擦冲量的计算 Dim clnew As collision '已经改变的碰撞
... Vr_all = Subtract(clnew.Va, clnew.Vb)
clnew.tangent_vel = Subtract(Vr_all, VScale(clnew.N, Dot(Vr_all, clnew.N)))'tangent_vel=Va-((Va·N-Vb·N)*N) '相切的速度 clnew.tangent_speed = VLength(clnew.tangent_vel) '相切的速度标量 If clnew.tangent_speed > 0 Then Dim T As D3DVECTOR D3DXVec3Scale T, clnew.tangent_vel, -1 / clnew.tangent_speed clnew.Ca = 1 / Boxa.m + D3DXVec3Dot(T, cross(VScale(cross(clnew.Ra, T), 1 / Boxa.Iz), clnew.Ra))'Ca = 1/m+((Ra×T)/Iz×Ra)T clnew.Cb = 1 / Boxb.m + D3DXVec3Dot(T, cross(VScale(cross(clnew.Rb, T), 1 / Boxb.Iz), clnew.Ra)) clnew.C = clnew.Ca + clnew.Cb
If clnew.C > 0 Then Const friction = 0.5 '动摩擦系数 Dim Ptt As Single '临时摩擦冲量 Ptt = clnew.tangent_speed / clnew.C If Ptt < friction * VLength(cl.Pn) Then '动静摩擦判断 clnew.Pt = Ptt Else clnew.Pt = friction * VLength(cl.Pn) End If
applyimpulse Boxa, VScale(T, clnew.Pt), collpos '应用摩擦冲量 applyimpulse Boxb, VScale(T, -clnew.Pt), collpos End If End If
刺透处理
为防止一物体刺穿另一物体,需要对刺穿进行处理.一个方法是检测时计算出刺入的深度,后在碰撞副加一微小冲量,使其分离.简单的考虑到一次就对半分离过于突然,不能取得最好的效果,所以每次以按一比例分离
另一个简单方法是直接修改刚体的位置: Boxa.pos = Add(VScale(colN, extra * 0.2), Boxa.pos) Boxb.pos = Add(VScale(colN, -extra * 0.2), Boxb.pos)
目前流行的物理引擎都是通过高级碰撞检测技术即未发生刺穿前�
|