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

转载请注明出处: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文件。

三、结语

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

时间: 2024-10-13 13:24:52

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

任意两个无限阶循环群之间的映上同态总是同构的

扩展为:任意两个无限接循环群总是同构的 设G关于二元运算"?"构成一个无限接循环群,记其单位元为e: 有循环群的定义,记G得生成元为a,则G=<a>;----即表示G中任何一个元素都可以表示为an; 由于任何一个无=无限阶循环群都与整数加群同构-----故问题等价于任何一个无限阶循环群都有整数加群同构: 证明两个群是同构的等价于构造一个同构映射 φ(n)=an 是整数加群到G的映射: 证明:φ是映射,任何相等相等的原像其像是相等的 证明:φ是同态 证明:φ是单射,满射 如何

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

背景 ? Spring Cloud现在已经被越来越多的公司采用了,微服务架构比传统意义上的单服务架构从复杂度上多了很多,出现了很多复杂的场景.比如,我们的产品是个app,支持第三方登录功能,在手机端调用第三方授权接口之后,返回了用户的相关信息,比如open_id,性别,头像等.这些信息我们需要保存在我们服务器上,当时针对头像是应该保存图片的url还是图片本身发生了歧义,在一番讨论之后,得出的结果是,我们需要通过url将图片下载到我们本地,然后调用我们自己的文件微服务中上传功能保存起来. 工具 I

通过lrzsz轻松实现Windows/Linux之间文件的上传/下载

在使用lrzsz之前一直都是用FTP来上传下载文件到Linux,在SecureCRT上安装了lrzsz之后个人觉得操作起来比使用FTP更为简单易用.并且可以方便的在本地PC机和远程服务器之间传输文件. 1.安装lrzsz 安装前先检查有没有安装lrzsz [[email protected]  ~]#rpm –ql lrzsz 没安装可以使用下列命令进行安装: [[email protected]  ~]#yum install lrzsz –y 2.配置上传/下载目录 3.安装好lrzsz软件

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

需求场景: 用户调用微服务1的接口上传一组图片和对应的描述信息.微服务1处理后,再将这组图片上传给微服务2进行处理.各个微服务能区分开不同的图片进行不同处理. 上一篇博客已经讨论了在微服务之间传递一组图片和对应参数的解决方案.现在来看看如何对组内文件进行区分.当前项目中使用了"commons-fileupload"和"feign-form"两个库进行文件传输. "commons-fileupload"库可以将http request转换成&quo

spring cloud实战与思考(二) 微服务之间通过fiegn上传多个文件1

需求场景: 微服务之间调用接口一次性上传多个文件. 上传文件的同时附带其他参数. 多个文件能有效的区分开,以便进行不同处理. Spring cloud的微服务之间接口调用使用Feign.原装的Feign不支持文件的传输.需要借助"Feign-form"库才行.但是貌似"Feign-form"库(至少是3.0.3版本)只支持单文件上传.在接口中使用多文件参数时会报异常: feign.codec.EncodeException: class [Lorg.springfr

十二,几何图形和图画

Path类是功能最强大的形状类,它能够包含任何简单形状.多级形状及更更复杂的曲线.Path.Data属性,该属性接受一个Geometry对象,该对象定义路径包含的一个或多个图形,Geometry是一个抽象类,指定Data时需要使用以下Geometry类的派生类: 路径和几何图形之间的区别:几何图形定义形状,而路径用于绘制形状,因此,Geometry对象为形状定义了坐标.尺寸等细节,而Path对象提供了绘制形状所使用的Stroke和Fill画刷,Path类还继承自UIElement基础架构中的特性

cocos2d-x开发中有关粒子系统的碰撞检测及可能性应用分析

游戏开发中,普通的碰撞检测就简单了,这主要是借助于精灵类的boundingBox矩形间是否相交来判定.但试想,如果在一个游戏中存在多种粒子武器,这两种武器互相朝对方开火,那么也应当存在一个粒子***相交(即碰撞)的问题吧.这时候如何检测呢? 今天在整理COCOS2D-X粒子系统支持时发现了这样的问题,而且碰到一个函数updateQuadWithParticle.这个函数在基类CCParticleSystem中定义如下: void CCParticleSystem::updateQuadWithP

这几个几何图形你会绘制吗

从城市宏伟的建筑到乡村简朴的住宅,从四通八达的立交桥到街头巷尾的交通标志,从古老的剪纸艺术到现代的城市雕塑,从自然界形态各异的动物到北京深奥的标志……你会发现图形世界是多姿多彩的!那么说到画图工具,最近小编偶得一个专业的绘图工具--几何画板,在学习了该软件后发现有很多绘图技巧,下面本几何画板教程就给大家亲身传授几个的绘图技巧. 技巧一.将圆奇数等分 几何画板是个好用的画图工具,不仅可以画几何图形,还可以将其进行等分,比如可以将圆奇数等分,具体步骤如下: 步骤一 打开几何画板,画一个圆:过圆心画一

[图形学] 《Real-Time Rendering》碰撞检测(一)

原文有35页,容我慢慢翻译,第一部分翻译了10页 reference:<Real-Time Rendering> 目录 17   前言 17.1 和射线的碰撞检测 17.2 使用BSP树的动态碰撞检测 17.3 一般层次的碰撞检测 17.3.1 分层的构建 17.3.2 不同层之间的碰撞检测 17.3.3 代价函数 17.4 OBB树 17.5 多重物体碰撞检测系统 17.5.1 广阶段的碰撞检测 17.5.2 总结 17.6 更多样的话题 17.6.1 及时碰撞检测 17.6.2 距离查询