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

一、概述

Direct2D中支持以下几种类型的几何图形:

  a.简单几何图形(Simple Geometry):矩形、圆角矩形、椭圆;

  b.路径图形(Path Geometry);

  c.复合图形(Composite Geometry):图形组、变换图形。

最近发现D2D除了可以绘制不同类型的几何图形之外,还有一个很强大的功能:对几何图形进行关系判断(也就是我们常说的碰撞检测)。

这里首先介绍一个D2D的一个接口类ID2D1Geometry。它用来表示一个几何对象资源,并定义一组用于处理和测量几何形状的帮助器方法。从 ID2D1Geometry 继承的接口将定义特定形状。上面提到的所有图形类都是ID2D1Geometry的子类。

下面我们就介绍一下几何图形的碰撞检测。

二、几何图形与点的碰撞检测

1.函数介绍

这里首先要介绍ID2D1Geometry接口的两个成员函数FillContainsPoint和StrokeContainsPoint,这两个函数涉及到我们将要进行的几何图形和点的碰撞检测,(这两个函数都有4个重载,这里由于篇幅原因只分别介绍重载中的一个,其实原理都一样,其他的重载大家可以去msdn官网了解):

(1)ID2D1Geometry::FillContainsPoint函数介绍

  功能:指示由该几何对象填充的区域是否包含指定点。
  参数
    point               要测试的点。
    worldTransform    进行包含测试前应用到该几何对象的转换。
    contains              此方法返回时将包含一个布尔值,表示几何图形是否包含point。必须为此参数分配存储空间。
  返回值:如果该方法成功,返回 S_OK;否则,将返回错误代码。

(2)ID2D1Geometry::StrokeContainsPoint函数介绍

  功能:确定几何对象的笔画是否包含指定的点。

  参数     

    point               要测试的点。

    strokeWidth   要应用的笔画粗细。

    strokeStyle    要应用的笔画样式。

    worldTransform   进行包含测试前应用到该几何对象的转换。     

    contains              此方法返回时将包含一个布尔值,表示几何图形的笔画(边框)包含point。必须为此参数分配存储空间。

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

2.代码实现

接下来我们就可以使用这个函数进行几何图形和点的碰撞检测工作了。我在代码中封装了两个函数PtInGeometry和PtInGeometryBorder,分别用来判断"点是否在几何图形内"和"点是否在几何图形(画笔)边框上"。

// 检测点是否在几何图形内
bool PtInGeometry(ID2D1Geometry* pGeometry, D2D1_MATRIX_3X2_F& transMatrix, D2D1_POINT_2F& pt)
{
BOOL contain = FALSE;
HRESULT hr = S_OK; hr = pGeometry->FillContainsPoint( pt, &transMatrix, &contain);
if (SUCCEEDED(hr) && contain)
{
return true;
} return false;
}
// 检测点是否在几何图形边框上
bool PtInGeometryBorder(ID2D1Geometry* pGeometry, float strokeWidth, D2D1_MATRIX_3X2_F& transMatrix, D2D1_POINT_2F& pt)
{
BOOL contain = FALSE;
HRESULT hr = S_OK; hr = pGeometry->StrokeContainsPoint( pt, strokeWidth, NULL, &transMatrix, &contain);
if (SUCCEEDED(hr) && contain)
{
return true;
} return false;
}

这样我们就可以确定点和几何图形之间的三种关系了:

  a.点在几何图形里面

  b.点在几何图形边框上

  c.点在几何图形外面

现在开始我们的测试,为了证明Direct2D可以判断任何几何图形和点的位置关系,使用一个五角星(路径几何图形)用当作检测的几何图形。这样做的想法是:既然复杂的路径几何图形都可以作这种判断,那么其他简单的几何图形当然也就没有任何问题啦!

在测试代码中,在窗口绘制的函数中绘制一个五角星(路径几何图形)用当作检测的几何图形,这里需要注意的是,为了让点和五角星之间的三种位置关系在演示效果中比较直观和明显,我将五角星填充色设置为银灰色;画两次边框(画笔),第一个边框(画笔)宽度设置为1,边框颜色设置为黑色;第二个边框(画笔)宽度设置为50,边框颜色设置为粉色并设为半透明。这样五角星的轮廓和边框就显而易见了,在黑色框内就是在五角星内,在粉色范围内就是在五角星边框上,在粉色边框外就是在五角星外。

之后绘制3个不同位置的点(注:由于Direct2D中没有直接绘制点的方法,使用边长为0的矩形代替点;为了我们的演示更清晰,这个边长为0的矩形绘制时画笔宽度为5,但是判断时仍然为点),在绘制点之前判断点和五角星的关系。如果点在五角星内部,绘制成红色;点在五角星边框上,绘制成紫色;点在五角星外面,绘制成绿色。这样在绘制结果中,我们就可以根据点的颜色来识别五角星和点的位置关系了。

最后贴一张测试Demo的效果图:

如上图中,三个点的位置和五角星之间的关系就一目了然了。

3.讨论

其实看到上面的演示图之后大家也能想到,其实点和几何图形的位置关系还有一种。这种比较特殊,就是在银灰色范围和粉色范围之间,有一个范围区域是银灰色和粉色叠加而成的深粉色(?感觉是这个颜色,怀疑自己是不是色弱...),这个区域就是我要说的第4种位置关系:既在五角星边框上,也在五角星内。如下图所示:

这是由于绘制边框的画笔是以边框为中心的,画笔的宽度不为0时,就会有一半的宽度覆盖到几何图形内,也就造成了这种特殊的位置关系。当然,如果几何图形在绘制时直接使用填充方式,而不绘制边框,那么我们就可以忽略这种特殊情况了。

还有一点需要注意的是,对五角星(几何对象)做变换之后,再和点作位置关系判断也是可以的。只是在我代码例子中,没有对五角星做变换。

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

三、结语

几何图形与点的碰撞检测到这里就介绍完了,下一篇文章我们将介绍几何图形之间的碰撞检测。

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

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

    转载请注明出处:http://www.cnblogs.com/Ray1024 一.概述 上一篇文章中我们介绍了几何图形与点的碰撞检测.几何图形与点的位置关系比较简单:点在几何图形内.点在几何图形外.点 ...

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

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

  3. linux CentOS 安装rz和sz命令 lrzsz 实现windows和linux之间的文件上传 下载

    https://blog.nbhao.org/1902.html https://bbs.csdn.net/topics/391989523 https://www.cnblogs.com/zhoul ...

  4. spring cloud实战与思考(二) 微服务之间通过fiegn上传一组文件(上)

    需求场景: 微服务之间调用接口一次性上传多个文件. 上传文件的同时附带其他参数. 多个文件能有效的区分开,以便进行不同处理. Spring cloud的微服务之间接口调用使用Feign.原装的Feig ...

  5. spring cloud实战与思考(三) 微服务之间通过fiegn上传一组文件(下)

    需求场景: 用户调用微服务1的接口上传一组图片和对应的描述信息.微服务1处理后,再将这组图片上传给微服务2进行处理.各个微服务能区分开不同的图片进行不同处理. 上一篇博客已经讨论了在微服务之间传递一组 ...

  6. Spring Cloud下使用Feign Form实现微服务之间的文件上传

    背景 ​ Spring Cloud现在已经被越来越多的公司采用了,微服务架构比传统意义上的单服务架构从复杂度上多了很多,出现了很多复杂的场景.比如,我们的产品是个app,支持第三方登录功能,在手机端调 ...

  7. Linux本机和远程服务器之间文件的上传和下载 rz sz

    tar zxvf lrzsz-0.12.20.tar.gz 解压安装包   下载地址:链接:https://pan.baidu.com/s/1KMS1QlyOhpXiYeaWdNBAyw 提取码:08 ...

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

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

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

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

随机推荐

  1. 为了让开发者写MaxCompute SQL更爽,DataWorks 增强SQL 编辑器功能

    众所周知,数据开发和分析的同学每天都要花大量时间写MaxCompute SQL:Dataworks作为数据开发的IDE直接影响着大家的开发效率,这次新上线的Dataworks我们在编辑体验上做了很多工 ...

  2. Hadoop HBase概念学习系列之HBase的Shell(步骤非常清晰)(二十四)

    这部分知识点,是必须要熟练玩转的! 见 5 hbase-shell + hbase的java api 的进入HBase Shell   强烈建议,先看我上面的这篇博文,是实实际际的步骤. 另外,附上一 ...

  3. nginx alias

    A path to the file is constructed by merely adding a URI to the value of the root directive. If a UR ...

  4. Java8新特性 -- 四大内置的核心函数式接口

    可以把这些函数式接口作为方法的参数. 1.0 核心内置函数式接口一: 消费型接口@FunctionalInterfacepublic interface Consumer<T> { voi ...

  5. RAC with asm on AIX, ORA-01114 error,with "gipcretAuthFail (22) " in ocssd.log

    I/O Errors in Alert log with ORA-29701, with "gipcWait failed with 16" in trace (文档 ID 149 ...

  6. Android学习路线总结,绝对干货(转)

    转自:https://www.cnblogs.com/yishaochu/p/5436094.html 一.前言 不知不觉自己已经做了几年开发了,由记得刚出来工作的时候感觉自己能牛逼,现在回想起来感觉 ...

  7. BI之报表测试总结

    报表测试总结: 1.测试准备工作: 数据准备 保证足够多的有效数据 清楚报表中涉及到的算法.公式 清楚业务功能接口 2.报表测试点 基本测试点:界面.控件.格式.布局.明显的数据错误.js报错.报表标 ...

  8. 以代码爱好者角度来看AMD与CMD(转)

    随着浏览器功能越来越完善,前端已经不仅仅是切图做网站,前端在某些方面已经媲美桌面应用.越来越庞大的前端项目,越来越复杂的代码,前端开发者们对于模块化的需求空前强烈.后来node出现了,跟随node出现 ...

  9. chrome 浏览器插件开发(一)—— 创建第一个chrome插件

    最近在开发一个chrome插件,在网上找到了一些的文章,虽说按照文章可以写出对应的例子,但若要进行实际开发,发现还是有不少文章中没有的坑.下面我将结合我在开发过程中遇到的几个方面,对这些坑做一下补充. ...

  10. iOS 单例模式简单实例

    单例模式主要实现唯一实例,存活于整个程序范围内,一般存储用户信息经常用到单例,比如用户密码,密码在登录界面用一次,在修改密码界面用一次,而使用单例,就能保证密码唯一实例.如果不用单例模式,init 两 ...