物理引擎探究(9)---球碰撞处理

0.简介

球的碰撞处理,之前想着会比较简单,但是实际上比想象的难一些。

1.球与球的碰撞

之所这么分类,所以因为球和球的碰撞比较特殊,目前暂时不考虑摩擦力的情况,球与球碰撞产生的碰撞交点是一定过两个球心的连线的,这样球就一定会因为碰撞产生位移。球的正碰是特殊情况,这里我们直接考虑球与球的斜碰,斜碰就是两个球碰撞时候,碰撞交点不在速度方向上。

关于斜碰后速度的变化可以看如下文章作为参考。

斜碰

我在这里也简要说明一下。

两个球碰撞,(上球为球A,下球为球B)

假设一个球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.代码

release0.04

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值