加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

圆形和矩形的碰撞检测

发布时间:2020-12-14 21:42:04 所属栏目:百科 来源:网络整理
导读:首先来说明一下核心思想 无非是三种状态: 1、圆心在矩形中 2、圆心在矩形外,但在其某一边的侧面 3、圆心在矩形外、不再某一边的侧面 圆心在矩形中的情况十分好处理,这里就不说了。 下面来说一下2、3情况的核心应对思路: 首先,拿到矩形的四个顶点。 算出


首先来说明一下核心思想


无非是三种状态:

1、圆心在矩形中

2、圆心在矩形外,但在其某一边的侧面

3、圆心在矩形外、不再某一边的侧面


圆心在矩形中的情况十分好处理,这里就不说了。

下面来说一下2、3情况的核心应对思路:


首先,拿到矩形的四个顶点。

算出圆心到四个顶点分别的距离。

给距离从小到大排一下序。

取其中两个最小距离的点,求出圆心到这两点之间直线(或延长线)上最短距离的那个点。

重点来了:

这时候要看这个点是在两点之间,还是在这条直线的延长线上。如果是之间,就是情况2。再延长线上就是3。
分别做处理,如果是情况2就算出两点距离,看看跟半径的关系判断是否碰撞。

如果是3就算出圆心到距离圆心最近的顶点的距离,看看它和半径的关系。


Lua代码如下:

(注:这个是本人洗澡的时候灵感突现想出的Idea,半夜写的算法。没有单独摘出来方法,将会在以后改进。请关注本人博客或Github: https://github.com/Schrodinger123)


--圆心,半径
	local circle = {
		x = 0,y = 0,r = 5
	}

	-- 矩形位置,宽高
	local box = {
		x = 5,y = 5,w = 3,h = 3
	}

	-- 矩形四个点
	box.ld = {
		x = box.x-box.w/2,y = box.y-box.h/2
	}

	box.rd = {
		x = box.x+box.w/2,y = box.y-box.h/2
	}

	box.lu = {
		x = box.x-box.w/2,y = box.y+box.h/2
	}

	box.ru = {
		x = box.x+box.w/2,y = box.y+box.h/2
	}

	-- 求两点间距离方法
	function p2pDis(p1,p2)
		return math.abs(math.sqrt(math.pow(p1.x-p2.x,2)+math.pow(p1.y-p2.y,2)))
	end

	-- 算出每个点距离圆心距离
	local line = {
		[1] = {dis = p2pDis(circle,box.ld),point = "ld"},[2] = {dis = p2pDis(circle,box.rd),point = "rd"},[3] = {dis = p2pDis(circle,box.lu),point = "lu"},[4] = {dis = p2pDis(circle,box.ru),point = "ru"},}

	-- 从小到大排序
	function ts(v1,v2)
		return v1.dis < v2.dis
	end
	table.sort(line,ts)

	-- 算出圆心在距离它最近的边(或边延长线)上的最近的点坐标
	local pointInLine = {}
	local status = 0 --0为竖着 1为横着
	if box[line[1].point].y == box[line[2].point].y then
		status = 1
	end

	pointInLine.x = status == 0 and box[line[1].point].x or circle.x
	pointInLine.y = status == 0 and circle.y or box[line[1].point].y

	-- 算距离
	if (status == 1 and (pointInLine.x < box.ld.x or pointInLine.x > box.rd.x)) or (status == 0 and (pointInLine.y < box.ld.y or pointInLine.y > box.lu.y)) then
		--完全在外边
		local p2nDis = p2pDis(circle,box[line[1].point])
		print("外距离"..p2nDis)
		print(p2nDis > circle.r and "不碰撞" or "碰撞")
	else
		--圆心在附近
		local p2lDis = p2pDis(circle,pointInLine)
		print("距离"..p2lDis)
		print(p2lDis > circle.r and "不碰撞" or "碰撞")
	end

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读