文档章节

圆与未旋转矩形的碰撞检测(上篇)

piggybear
 piggybear
发布于 2015/02/16 10:33
字数 999
阅读 24
收藏 0
点赞 0
评论 0

我们以Cocos2d-x Lua脚本来说明圆与未旋转矩形的碰撞检测,原理才是重点,本文参照了两种方法。


第一种方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
bool  intersects(CircleType circle, RectType rect)
{   
     //1
     circleDistance.x =  abs (circle.x - rect.x);
     circleDistance.y =  abs (circle.y - rect.y);
 
    //2
     if  (circleDistance.x > (rect.width/2 + circle.r)) {  return  false ; }
     if  (circleDistance.y > (rect.height/2 + circle.r)) {  return  false ; }
 
    //3
     if  (circleDistance.x <= (rect.width/2)) {  return  true ; } 
     if  (circleDistance.y <= (rect.height/2)) {  return  true ; }
 
    //4
     cornerDistance_sq = (circleDistance.x - rect.width/2)^2 +
                          (circleDistance.y - rect.height/2)^2;
 
     return  (cornerDistance_sq <= (circle.r^2));
}

circle.x, circle.y为圆心;rect.x, rect.y为矩形的中心。如图:

20140820162719449.jpg

代码注释:

  1. 第一对语句计算圆的中心到矩形中心的x与y的差值的绝对值。将四个象限重合为一个,这样就不需要计算四次。注意,这里只显示了第一象限。灰色区域代表矩形,红色边界轮廓的临界区域与矩形的距离正是一个半径的长度。圆的中心必须在这个红色十字交叉的边界处。

  2. 第二对语句判断圆与矩形(在任何一个方向中)之间的距离很大不会出现交叉的简单的情况。如图中绿色区域所示。

  3. 第三对语句判断圆与矩形(在任何一个方向中)之间的距离很小,一定会产生交叉简单的情况。如图中橘色和灰色的交叉区域。注意,必须在第二步完成之后做这一步的判断,以便更合逻辑。

  4. 最后两句判断圆和矩形的一角可能相交的复杂情况,计算圆心到角的距离,然后验证这个距离不超过圆的半径。若圆心在红色阴影区内,则结果返回FALSE;若圆心在白色阴影区内,则结果返回TRUE。

(翻译自:http://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection


第二种方法,检测圆和矩形碰撞,要找到矩形上离圆的中心点最近的点计算

1
2
3
if  circle.x < box.x then
    cx = box.x
end

如果圆在矩形的左边,离着圆中心点最近的矩形上的点在矩形的左边边界上

20140820154035796.jpg

1
2
elseif circle.x > box.x + box.width then
    cx = box.x + box.width


如果圆的中心点在矩形的右边,离着圆中心点最近的矩形上的点在矩形的右边边界上

20140820154657857.jpg

1
2
else
    cx = circle.x


如果圆心x既不在矩形的左边也不在右边, 那么cx就在矩形内

20140820155027443.jpg

同理,找到Y方向上离着圆中心点最近的y偏移cy

1
2
3
4
5
6
7
     if  circle_pt.y < rect.y then
         cy = rect.y
     elseif circle_pt.y > rect.y + rect.height then
         cy = rect.y + rect.height
     else
         cy = circle_pt.y
     end


最后附上Lua版的圆与矩形的碰撞,圆与圆的碰撞检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
--[[--
 
检测圆和未旋转的矩形之间的碰撞
参考:http: //lazyfoo.net/SDL_tutorials/lesson19/index.php
 
~~~ lua
 
local intersects = circleIntersectRect(cc.p(10, 10), 50, cc.rect(20, 20, 100, 100))
 
~~~
 
param: circle_pt 圆心
param: radius 半径
param: rect 矩形 {x=0,y=0,width=100,height=100}
 
@see 
 
]]
function circleIntersectRect(circle_pt, radius, rect)
     local cx = nil
     local cy = nil
 
     -- Find the point on the collision box closest to the center of the circle
     if  circle_pt.x < rect.x then
         cx = rect.x
     elseif circle_pt.x > rect.x + rect.width then
         cx = rect.x + rect.width
     else
         cx = circle_pt.x
     end
 
     if  circle_pt.y < rect.y then
         cy = rect.y
     elseif circle_pt.y > rect.y + rect.height then
         cy = rect.y + rect.height
     else
         cy = circle_pt.y
     end
 
     if  cc.pGetDistance(circle_pt, cc.p(cx, cy)) < radius then
         return  true
     end
 
     return  false
end
 
 
--[[--
 
检测圆之间的碰撞
 
~~~ lua
 
local intersects = circleIntersects(cc.p(10, 10), 10, cc.p(20,20), 20)
 
~~~
 
@param : circle_pt_a 圆A中心
@param : radius_a 圆A半径
@param : circle_pt_b 圆B中心
@param : radius_b 圆B半径
 
@ return  是否碰撞
 
@see 
 
]]
function circleIntersects(circle_pt_a, radius_a, circle_pt_b, radius_b)
     -- If the distance between the centers of the circles is less than the sum of their radius
     if  cc.pGetDistance(circle_pt_a, circle_pt_b) < (radius_a + radius_b) then
         return  true
     end
     return  false
end


参考:

Circular Collision Detection


来源网址:http://blog.csdn.net/teng_ontheway/article/details/38706837

分享到:

本文转载自:http://blog.csdn.net/aa294194253/article/details/39208469

共有 人打赏支持
piggybear
粉丝 3
博文 237
码字总数 37552
作品 0
西安
技术主管
26、《每周一点canvas动画》——3D旋转与碰撞

各位同学实在不好意思,最近忙着面试找工作,耽搁了一个星期。由于前一篇文章的关注的量比较多,让我决定以后的文章尽量多加一些高质量的DEMO和配图。可能这比较耗费时间,但质量才是王道,希...

qq_39759115 ⋅ 04/17 ⋅ 0

2.5d 游戏开发引擎--IndieLib

IndieLib是一个 2.5d引擎,使用它可以简化游戏开发的难度,提高游戏开发的速度。内部它使用Direct3d做硬件加速,但它并没有使用DirectDraw或者 ID3DXSprite,而是直接将材质渲染在多边形上。...

匿名 ⋅ 2012/03/31 ⋅ 0

13.7-全栈Java笔记:打飞机游戏实战项目|Rectangle|intersects|Plane

碰撞类检测技术 游戏中,碰撞是遇到最频繁的技术。当然,很多游戏引擎内部已经做了碰撞检测处理,我们只需调用即可。本节课是从碰撞的原理进行讲解,大家自己去实现基本的碰撞检测。 矩形检测...

全栈Java ⋅ 2017/08/04 ⋅ 0

LibGDX_7.4: 碰撞检测 与 矩形包围区域(Rectangle)

本文链接: http://blog.csdn.net/xietansheng/article/details/50188157 LibGDX 基础教程(总目录) 1. Rectangle 概述 Rectangle 类表示一个 2D 矩形,封装了 2D 矩形的 左下角坐标 和 宽高...

xietansheng ⋅ 2015/12/07 ⋅ 0

Pongo网页版JavaScript源代码及设计思路

1.游戏背景介绍(写在前面的废话): 五月初的某天,看到某网推荐了这款游戏,Pongo,看着还不错的样子就用ipad下下来试玩了下,玩了两局感觉还错挺过瘾的,因为是手欠类游戏嘛大家懂的。 但是...

ChenReason ⋅ 2014/06/14 ⋅ 0

HT for Web可视化QuadTree四叉树碰撞检测

QuadTree四叉树顾名思义就是树状的数据结构,其每个节点有四个孩子节点,可将二维平面递归分割子区域。QuadTree常用于空间数据库索引,3D的椎体可见区域裁剪,甚至图片分析处理,我们今天介绍...

xhload3d ⋅ 2014/12/06 ⋅ 0

HTML5实现3D和2D可视化QuadTree四叉树碰撞检测

QuadTree四叉树顾名思义就是树状的数据结构,其每个节点有四个孩子节点,可将二维平面递归分割子区域。QuadTree常用于空间数据库索引,3D的椎体可见区域裁剪,甚至图片分析处理,我们今天介绍...

xhload3d ⋅ 2015/12/14 ⋅ 3

当 iOS 游戏开发像做份沙拉那么简单

感谢@雷锋网的投稿: 写在所有之前:这个工具更适合没有编码基础又喜欢折腾的设计师们,并不一定适合开发者。 当你有一个好的游戏创意却因没有代码基础而搁浅时,是不是很期待一款这样的软件...

红薯 ⋅ 2011/12/05 ⋅ 2

Android游戏开发之检测游戏碰撞的原理实现(九)

雨松MOMO带你走进游戏开发的世界之游戏碰撞的原理 雨松MOMO原创文章如转载,请注明:转载自雨松MOMO的博客原文地址:http://blog.csdn.net/xys289187120/article/details/6630302 游戏碰撞的大...

彭博 ⋅ 2012/03/09 ⋅ 0

Android游戏开发之检测游戏碰撞的原理实现(九)

雨松MOMO带你走进游戏开发的世界之游戏碰撞的原理 雨松MOMO原创文章如转载,请注明:转载自雨松MOMO的博客原文地址:http://blog.csdn.net/xys289187120/article/details/6630302 游戏碰撞的大...

晨曦之光 ⋅ 2012/03/07 ⋅ 1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

从 Confluence 5.3 及其早期版本中恢复空间

如果你需要从 Confluence 5.3 及其早期版本中的导出文件恢复到晚于 Confluence 5.3 的 Confluence 中的话。你可以使用临时的 Confluence 空间安装,然后将这个 Confluence 安装实例升级到你现...

honeymose ⋅ 今天 ⋅ 0

用ZBLOG2.3博客写读书笔记网站能创造今日头条的辉煌吗?

最近两年,著名的自媒体网站今日头条可以说是火得一塌糊涂,虽然从目前来看也遇到了一点瓶颈,毕竟发展到了一定的规模,继续增长就更加难了,但如今的今日头条规模和流量已经非常大了。 我们...

原创小博客 ⋅ 今天 ⋅ 0

MyBatis四大核心概念

本文讲解 MyBatis 四大核心概念(SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper)。 MyBatis 作为互联网数据库映射工具界的“上古神器”,训有四大“神兽”,谓之:Sql...

waylau ⋅ 今天 ⋅ 0

以太坊java开发包web3j简介

web3j(org.web3j)是Java版本的以太坊JSON RPC接口协议封装实现,如果需要将你的Java应用或安卓应用接入以太坊,或者希望用java开发一个钱包应用,那么用web3j就对了。 web3j的功能相当完整...

汇智网教程 ⋅ 今天 ⋅ 0

2个线程交替打印100以内的数字

重点提示: 线程的本质上只是一个壳子,真正的逻辑其实在“竞态条件”中。 举个例子,比如本题中的打印,那么在竞态条件中,我只需要一个方法即可; 假如我的需求是2个线程,一个+1,一个-1,...

Germmy ⋅ 今天 ⋅ 0

Springboot2 之 Spring Data Redis 实现消息队列——发布/订阅模式

一般来说,消息队列有两种场景,一种是发布者订阅者模式,一种是生产者消费者模式,这里利用redis消息“发布/订阅”来简单实现订阅者模式。 实现之前先过过 redis 发布订阅的一些基础概念和操...

Simonton ⋅ 今天 ⋅ 0

error:Could not find gradle

一.更新Android Studio后打开Project,报如下错误: Error: Could not find com.android.tools.build:gradle:2.2.1. Searched in the following locations: file:/D:/software/android/andro......

Yao--靠自己 ⋅ 昨天 ⋅ 0

Spring boot 项目打包及引入本地jar包

Spring Boot 项目打包以及引入本地Jar包 [TOC] 上篇文章提到 Maven 项目添加本地jar包的三种方式 ,本篇文章记录下在实际项目中的应用。 spring boot 打包方式 我们知道,传统应用可以将程序...

Os_yxguang ⋅ 昨天 ⋅ 0

常见数据结构(二)-树(二叉树,红黑树,B树)

本文介绍数据结构中几种常见的树:二分查找树,2-3树,红黑树,B树 写在前面 本文所有图片均截图自coursera上普林斯顿的课程《Algorithms, Part I》中的Slides 相关命题的证明可参考《算法(第...

浮躁的码农 ⋅ 昨天 ⋅ 0

android -------- 混淆打包报错 (warning - InnerClass ...)

最近做Android混淆打包遇到一些问题,Android Sdutio 3.1 版本打包的 错误如下: Android studio warning - InnerClass annotations are missing corresponding EnclosingMember annotation......

切切歆语 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部