转载请注明出处:http://www.cnblogs.com/Ray1024

一、概述

上一篇文章中我们介绍了几何图形与点的碰撞检测。几何图形与点的位置关系比较简单:点在几何图形内、点在几何图形外、点在几何图形边框上三种情况。

几何图形之间的位置关系就比较复杂了,大概有4种位置关系。这几种关系大家应该都知道:不相交、相交、包含、属于(被包含)。

今天我们来介绍一下几何图形之间的碰撞检测。

二、几何图形之间的碰撞检测

1.函数介绍

首先还是要先介绍ID2D1Geometry接口的一个成员函数CompareWithGeometry,这个函数是我们接下来要进行几何图形之间的碰撞检测的关键,(这个函数有4个重载,这里由于篇幅原因只分别介绍重载中的一个,其实原理都一样,其他的重载大家可以去msdn官网了解):

  ID2D1Geometry::CompareWithGeometry函数介绍

    功能:描述此几何对象与指定几何对象之间的交集。

    参数

      inputGeometry        要测试的几何对象。

      inputGeometryTransform  要应用到 inputGeometry的转换。

      relation            此方法返回时,relation表示此几何对象与inputGeometry的关系。

    返回值:如果该方法成功,则返回 S_OK。 否则,将返回错误代码。

ID2D1Geometry::CompareWithGeometry函数的第3个参数用来返回此几何对象与inputGeometry的关系,这个参数是一个枚举类型D2D1_GEOMETRY_RELATION,我们简单看一下它的枚举成员都有哪些:

typedef enum
{
D2D1_GEOMETRY_RELATION_UNKNOWN = 0, // 无法确定
D2D1_GEOMETRY_RELATION_DISJOINT = 1, // 不相交
D2D1_GEOMETRY_RELATION_IS_CONTAINED = 2, // 属于(被包含)
D2D1_GEOMETRY_RELATION_CONTAINS = 3, // 包含
D2D1_GEOMETRY_RELATION_OVERLAP = 4 // 相交
} D2D1_GEOMETRY_RELATION;

从上面的介绍就可以看出,几何图形之间的位置关系有4种:不相交、属于、包含和相交。枚举的第一个成员D2D1_GEOMETRY_RELATION_UNKNOWN在MSDN中是这样介绍的,需要注意的是任何D2D方法都不会返回该值。

介绍完我们需要用到的函数,我们接下来就可以使用这个函数进行几何图形之间的碰撞检测工作了。

2.首先解决一个小问题

我们先看一下下面的函数使用示例:

hr = pGeometry1->CompareWithGeometry(
pGeometry2,
transMatrix2,
&relation
);

在这段代码中,出现一个问题:在使用CompareWithGeometry函数判断几何图形之间的位置关系时,只允许参数中的几何对象pGeometry2传入对应的变换,而不允许自身的几何对象pGeometry1传入自己的变换。这样就出现了我们使用这个函数不能满足的情况:如果自身的几何对象也有变换,那么就不能直接使用CompareWithGeometry函数了。

但是,我们可以间接地弥补一下这个缺陷。

在ID2D1Geometry中,有一个子类接口ID2D1TransformedGeometry,它用来表示已转换的几何对象。有了这个接口,我们就可以先使用几何对象pGeometry1和它对应的变换创建一个已转换的几何对象transGeometry,之后再用transGeometry判断其与几何对象pGeometry2的位置关系,这样就可以完美解决这个问题了。

代码如下:

// 使用pGeometry1和transMatrix1创建transGeometry对象
HRESULT hr = pD2DFacytory->CreateTransformedGeometry(
pGeometry1,
transMatrix1,
&transGeometry
); if (SUCCEEDED(hr))
{
// 使用transGeometry和pGeometry2做位置判断
hr = transGeometry->CompareWithGeometry(
pGeometry2,
transMatrix2,
&relation
); // 使用relation做接下去的工作
// ...
}

3.代码实现

根据上面的函数介绍和问题分析,我在代码中封装了一个函数IntersectsWithGeometry,用来判断几何图形之间的位置关系。代码如下:

// 检测两个几何图形是否碰撞
D2D1_GEOMETRY_RELATION IntersectsWithGeometry(ID2D1Factory* pD2DFacytory,
ID2D1Geometry* pGeometry1, D2D1_MATRIX_3X2_F& transMatrix1,
ID2D1Geometry* pGeometry2, D2D1_MATRIX_3X2_F& transMatrix2)
{
D2D1_GEOMETRY_RELATION relation;
ID2D1TransformedGeometry* transGeometry = NULL; HRESULT hr = pD2DFacytory->CreateTransformedGeometry(
pGeometry1,
transMatrix1,
&transGeometry
); if (SUCCEEDED(hr))
{
hr = transGeometry->CompareWithGeometry(
pGeometry2,
transMatrix2,
&relation
); if (SUCCEEDED(hr))
{
SafeRelease(&transGeometry);
return relation;
}
SafeRelease(&transGeometry);
} return D2D1_GEOMETRY_RELATION_UNKNOWN;
}

此函数在使用时,传入D2D工厂,几何对象1,几何对象1的变换矩阵,几何对象2,几何对象2的变换矩阵 作为参数列表,返回几何对象1和几何对象2的位置关系。

现在开始我们的测试,在测试代码中,我还是使用了五角星作为几何对象比较的标准,分别创建了五角星、圆角矩形、矩形、圆形和三角形。原始状态即不做碰撞检测时,五个几何对象的初始状态如下图,五角星作为比较的标准,它的颜色为蓝色,其余四个几何对象的初始颜色均为白色。

这是不做碰撞检测时的效果图:

进行测试时,使用五角星分别去与这四个几何对象进行比较。为了让大家从绘制的结果图中清楚地看出这些几何对象的位置关系,在我的代码中,会根据比较之后返回的结果,来设置它们绘制的颜色,不同的位置关系的几何对象绘制颜色不同。

我使用的颜色标准为:

  a.不相交  红色

  b.属于   橙色

  c.包含   黄色

  d.相交   绿色

那么比较之后再进行绘制,我们最后的效果图是这样的:

上图的测试的结果表明:

  (1)五角星  属于    圆角矩形

  (2)五角星  相交于   矩形

  (3)五角星  包含    圆形

  (4)五角星  不相交于  三角形

在这里完整代码代码就不贴出了,有兴趣的朋友可以点击此处下载Demo源码,Demo源码是Direct2DTests目录下的D2DCollisionDetectionBetweenGeometrys文件。

三、结语

这样,我们所作的几何图形之间的碰撞检测工作就完成了。其实准确来说,我们做的不是几何图形之间的碰撞检测工作,而是几何图形之间的位置关系判断。因为碰撞检测绝大部分情况只是需要判断几何图形是不是相交,而我们这里不仅可以判断它们是不是相交,还可以更精确的判断出它们是不是包含或被包含(属于)的关系。只不过我最近在用D2D写引擎,说碰撞检测比较习惯了。

但是,通过这篇文章,我们可以知道,D2D对几何图形之间的关系判断足够可以满足我们的需求了。

Direct2D处理几何图形之间的碰撞检测(下)的更多相关文章

  1. Direct2D处理几何图形之间的碰撞检测(上)

    转载请注明出处:http://www.cnblogs.com/Ray1024 一.概述 Direct2D中支持以下几种类型的几何图形: a.简单几何图形(Simple Geometry):矩形.圆角矩 ...

  2. cocos2d-x游戏开发系列教程-坦克大战游戏之所有坦克之间的碰撞检测

    上篇我们完成了简单的AI编写,但是各个坦克移动时之间是可以重合的, 这节课我们来完成坦克之间的碰撞检测,还是在上篇的EnemyAI中完成. 1.我先现在坦克类Tank中添加两个成员变量: CC_SYN ...

  3. 【转】深层次探讨mutex与semaphore之间的区别(下)

    原文网址:http://blog.chinaunix.net/uid-23769728-id-3173282.html 这篇博文很长,虽然这是下篇,但还没结束,benchmark方面的东西正在进行中, ...

  4. 2016/3/24 ①数据库与php连接 三种输出fetch_row()、fetch_all()、fetch_assoc() ②增删改时判断(布尔型) ③表与表之间的联动 ④下拉菜单 ⑤登陆 三个页面

    ①数据库与php连接   图表 header("content-type:text/html;charset=utf-8"); //第一种方式: //1,生成连接,连接到数据库上的 ...

  5. [Unity3D插件]2dToolKit系列三 碰撞检测功能的实现以及障碍物的随机摆放

    貌似有一段时间没更新2dtoolkit系列了,这段时间一直在忙着其他事情,今天开始继续这个插件系列的教程,网上搜索,貌似关于这个插件的教程无非还是跟官方的教程很类似,有的甚至都没有自己照着亲手实践一遍 ...

  6. NeHe OpenGL教程 第三十课:碰撞检测

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  7. “等一下,我碰!”——常见的2D碰撞检测

    转自:https://aotu.io/notes/2017/02/16/2d-collision-detection/ 在 2D 环境下,常见的碰撞检测方法如下: 外接图形判别法 轴对称包围盒(Axi ...

  8. “AS3.0高级动画编程”学习:第一章高级碰撞检测

    AdvancED ActionScript 3.0 Animation 是Keith Peters大师继"Make Things Move"之后的又一力作,网上已经有中文翻译版本了 ...

  9. Win10系列:VC++绘制几何图形1

    本小节主要介绍如何使用Direct2D来绘制几何图形,其中会使用到FillGeometry函数和FillEllipse函数,FillGeometry函数用于填充几何图形的内部区域,而FillEllip ...

随机推荐

  1. VRSProcess(一)

    1.freopen( "CONOUT$","w",stdout);在操作系统中,命令行控制台(即键盘或者显示器)被视为一个文件,既然是文件,那么就有“文件名”. ...

  2. #003 React 组件 继承 自定义的组件

    主题:React组件 继承 自定义的 组件 一.需求说明 情况说明: 有A,B,C,D 四个组件,里面都有一些公用的逻辑,比如 设置数据,获取数据,有某些公用的的属性,不想在 每一个 组件里面写这些属 ...

  3. 预估高并发下API服务器数量

    我的主要工作就是API的编写,应该关注API的响应时间,以及并发时候的响应.那么如何测试API响应时间,以及预计高并发服务器压力呢? 从访问日志开始查起. 1 首先统计API每日访问总数.举例假设某个 ...

  4. 我对git的快速使用和理解

    收藏较好的,分享给大家 https://mp.weixin.qq.com/s/k4tU8snvssyKJ2WkvkFrZA

  5. tyvj1953 Normal

    题目链接 正解:点分治+$FFT$. 很想吐槽一下$bzoj$,为什么搬了别的$oj$的题还设成权限题.. 首先我们考虑期望的线性性,即考虑每个点的贡献. 显然每个点的贡献就是它在点分树上的深度,所以 ...

  6. Java 中 Emoji 的正则表达式

    一.emoji 的范围 查阅维基百科中 emoji 的说明 1. 杂项符号及图形 杂项符号及图形一共有768个字符,范围为: U+1F300 - U+1F5FF,在 Java 中正则表达式为: &qu ...

  7. Python基本知识3----序列

    前言: 序列:列表/元组/字符串 3种序列的共同点: 都可以通过索引得到每一个元素 默认索引值从0开始(还支持负数) 都可以通过切片的方式得到范围内的元素的集合 有很多共同的操作符(重复操作符.拼接操 ...

  8. MySQL(一)索引的创建和删除

    索引是存储引擎用于快速找到记录的一种数据结构,这是索引的基本功能. 索引对于良好的性能非常关键.尤其是当表中的数据量越来越大时,索引对性能的影响愈发重要.接下来将讲述如何创建.查看和删除索引. 索引分 ...

  9. java学习笔记-JavaWeb篇二

    JavaWEB篇二 45 HttpSession概述46 HttpSession的生命周期 47 HttpSession常用方法示例48 HttpSessionURL重写 49 HttpSession ...

  10. 【题解】洛谷P1169 [ZJOI2007] 棋盘制作(坐标DP+悬线法)

    次元传送门:洛谷P1169 思路 浙江省选果然不一般 用到一个从来没有听过的算法 悬线法: 所谓悬线法 就是用一条线(长度任意)在矩阵中判断这条线能到达的最左边和最右边及这条线的长度 即可得到这个矩阵 ...