物理引擎探究(7)---第一次碰撞

0.简介

碰撞是比较难写的部分,但是也不难写,掌握了规律就好办不少,这次实现一个最简单的碰撞判断。

1.圆圈与直线的碰撞

上一次实现了直线,严谨来说是线段,圆圈与一条线段的碰撞,方法有很多,不要拘泥于我接下来要介绍的一种方法。

首先我利用圆圈的圆心,将圆心O投影到线段所在直线上作为点C,线段的端点是A和B,如果C在AB之间,则向量CA与CB的夹角应该是180度,此时计算圆心到C点距离,如果比半径小就是相交了。如下图所示。

示意图1

当然这还不够,如果C在AB之外,则CA与CB的夹角是0度,这个夹角就是体现在两个向量的COS值上。

接下来要计算圆心O与A和B两个端点的距离,如果小于半径则相交。

示意图2
CollideInfo collide::LineAndCircle(Object * line,Object * circle)
{
	Line* linePtr = dynamic_cast<Line*>(line);
	Circle * circlePtr = dynamic_cast<Circle*>(circle);
	vec3 A = linePtr->A + linePtr->position;
	vec3 B = linePtr->B + linePtr->position;
	vec3 O = circlePtr->position;
	//C点是圆心到直线的投影
	vec3 AB = B - A;
	vec3 C = A + AB * (dot(AB, (O - A)) / dot(AB, AB));
	//判断投影点是否在点段内
	float distance = length(C - O);
	//如果投影点在线段内
	if (abs(dot(normalize(C - A), normalize(C - B))+1)<0.0001)
	{
		//若在的时候,判断两点距离是不是小于半径
		
		if (distance < circlePtr->radius)
		{
			while (1);
			return CollideInfo(line,circle,abs(circlePtr->radius - distance),normalize(C-O));
		}
		return CollideInfo(nullptr, nullptr, 0, vec3(0, 0, 0));
	}
	else
	{
		float disOA = length(O -A);
		float disOB = length(O -B);
		if (disOA < circlePtr->radius)
		{
			while (1);
			return CollideInfo(line, circle, abs(circlePtr->radius - disOA), normalize(O - A));
		}
		if (disOB < circlePtr->radius)
		{
			while (1);
			return CollideInfo(line, circle, abs(circlePtr->radius - disOB), normalize(O - B));
		}
	}
	return CollideInfo(nullptr, nullptr, 0, vec3(0,0,0));
}

目前碰撞还没有什么效果,我在碰撞位置加上一个死循环,这样一旦碰撞后程序就不动了。

2.效果

两张情况

3.源码

release0.02

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值