物理引擎探究(9)---球碰撞处理
程序员文章站
2022-07-04 20:06:37
...
0.简介
球的碰撞处理,之前想着会比较简单,但是实际上比想象的难一些。
1.球与球的碰撞
之所这么分类,所以因为球和球的碰撞比较特殊,目前暂时不考虑摩擦力的情况,球与球碰撞产生的碰撞交点是一定过两个球心的连线的,这样球就一定会因为碰撞产生位移。球的正碰是特殊情况,这里我们直接考虑球与球的斜碰,斜碰就是两个球碰撞时候,碰撞交点不在速度方向上。
关于斜碰后速度的变化可以看如下文章作为参考。
斜碰
我在这里也简要说明一下。
假设一个球A以速度V运动,与另一个静止的球B碰撞,此时将速度根据两个圆心方向和对应垂直方向分解,得到V1和V2,V2就是与另一个球B进行动量守恒计算的速度,加入计算完毕后,V2方向在碰撞后的速度是V3,V1+V3则是A球最终的运动结果,同理球B也这样计算,最终求得两个球的运动速度。具体还可以看上面的链接,斜碰。
2.实现
class CollideInfo
{
public:
CollideInfo() {}
CollideInfo(Obj_Forces*_A, Obj_Forces*_B,float _deep,vec3 _cPoint):A(_A),B(_B),deep(_deep), cPoint(_cPoint) {}
Obj_Forces* A;
Obj_Forces* B;
float deep;//相交最短距离
vec3 cPoint;//碰撞点
//生成力
void generate()
{
//没有碰撞就不计算
if (A == nullptr || B == nullptr)
return;
//以下生成的都是碰撞产生的力
//两个物体都存在说明产生碰撞力
if (A != nullptr && B != nullptr)
{
vec3 vecA = normalize(A->obj->position - cPoint);
vec3 vecB = normalize(B->obj->position - cPoint);
//碰撞点在两个型心连线上
if (dot(vecA, vecB) < 0.0001)
{
float speedA = length(A->obj->velocity);
float speedB = length(B->obj->velocity);
float cosa = dot(vecA, normalize(A->obj->velocity));
float cosb = dot(vecB, normalize(B->obj->velocity));
if (speedA == 0)
cosa = 1;
if (speedB == 0)
cosb = 1;
//两个物体的速度分解,碰撞点到连心线上的分解
vec3 rA = momentumCalc(A->obj->mass, B->obj->mass, speedA * cosa*vecA, speedB * cosb*vecB);
vec3 rB = momentumCalc(B->obj->mass, A->obj->mass, speedB * cosb*vecB, speedA * cosa*vecA);
vec3 AC = vecA * speedA * cosa;
vec3 BC = vecB * speedB * cosb;
vec3 AR = A->obj->velocity - AC;
vec3 BR = B->obj->velocity - BC;
AC = rA;
BC = rB;
A->obj->velocity = AC + AR;
B->obj->velocity = BC + BR;
}
//受力计算
vec3 force(0,0,0);
for (auto fa : A->forces)
{
force += fa->getForce();
}
A->addForce(new Elastic(-force,COLLIDEFORCE));
force = vec3(0, 0, 0);
for (auto fb : B->forces)
{
force += fb->getForce();
}
B->addForce(new Elastic(-force, COLLIDEFORCE));
}
}
vec3 momentumCalc(float mA, float mB, vec3 vA, vec3 vB)
{
return ((mA-mB)*vA+2.0f*mB*vB)/(mA+mB);
}
~CollideInfo() {}
};
这里确实废了不小力气(找资料时间比较久),不过还好可以实现,后续再优化计算过程。当然,之前的直线与球碰撞代码就删除了,因为考虑的情况比较少,只是暂时测试碰撞信息处理模块用的。
3.效果
4.代码
上一篇: 物理引擎探究(8)---碰撞处理
下一篇: 数据结构 稀疏矩阵的压缩方法 待补充