




已阅读5页,还剩2页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
判断点在多边形内部0.前言最近不断遇到类似的几何位置问题,一直没有花时间去总结,本文总结了我常用点跟多边形的位置判断方法以及代码。希望能够对大家有所帮助。文中所指的多边形均为凸多边形,一些描述可能有误,欢迎指正。1.测试的多边形在开始之前,我们需要先构建好测试环境。我构建了一个比较特殊的多边形,如下。/ | |_|从最上面的顶点顺时针坐标(屏幕坐标系)分别为:(40,10)(60,30)(60,50)(20,50)(20,30)2.射线判别法根据对多边形的了解,我们可以得出如下结论:如果一个点在多边形内部,任意角度做射线肯定会与多边形要么有一个交点,要么有与多边形边界线重叠。如果一个点在多边形外部,任意角度做射线要么与多边形有一个交点,要么有两个交点,要么没有交点,要么有与多边形边界线重叠。利用上面的结论,我们只要判断这个点与多边形的交点个数,就可以判断出点与多边形的位置关系了。首先罗列下注意事项:l射线跟多边形的边界线重叠的情况l区别内部点和外部点的射线在有一个交点时的情况对于第一个注意事项,可以将射线角度设为零度,这样子只需要判断两个相邻顶点的Y值是否相等即可。然后再判断这个点的X值方位。对于第二个注意事项,网上许多文章都说到做射线以后交点为奇数则表示在多边形内部,这是一个错误的观点,不仅对于凹多边形不成立,对于凸多边形也不成立。例如:从外部点做射线刚好经过一顶点,这样子交点个数就为奇数,但是该点却不在多边形内部。至于要如何区分这两种情况呢,我能想到了一个不完美的方法,外部点的射线跟多边形有一个交点的时候,该交点肯定为顶点,如果该射线上移一位或者下移一位,要么变成有两个交点要么没有交点。当然为了安全起见,这里把射线尽量往相邻点中心移动。这样子就能够判断出是外部点的射线跟多边形有一个交点。不过这个方法并不完美,因为有了移位操作,可能会把内部点移动出外部。而且如果判断点在(60,30)位置,判断的时候先遇到(20,30),然后移位操作,就判断就出错了。为了解决这些问题,我在起初先扫描一次判断点是否在顶点上虽然影响了一点效率,而且当判定点距离多边形一个单位时,判断可能会有误。不过只要不是需要高精度的话,这个方法还是很有效的。代码如下:bool InsidePolygon1( POINTD *polygon,int N,POINTD pt ) int i,j; bool inside,redo; redo = true; for (i = 0;i N;+i) if (polygoni.x = pt.x & / 是否在顶点上 polygoni.y = pt.y ) redo = false; inside = true; break; while (redo) redo = false; inside = false; for (i = 0,j = N - 1;i N;j = i+) if ( (polygoni.y pt.y & pt.y polygonj.y) | (polygonj.y pt.y & pt.y polygoni.y) ) if (pt.x = polygoni.x | pt.x = polygonj.x) double _x = (pt.y-polygoni.y)*(polygonj.x-polygoni.x)/(polygonj.y-polygoni.y)+polygoni.x; if (pt.x _x) / 在线的左侧 inside = !inside; else if (pt.x = _x) / 在线上 inside = true; break; else if ( pt.y = polygoni.y) if (pt.x polygonj.y ? -pt.y : +pt.y; redo = true; break; else if ( polygoni.y = polygonj.y & / 在水平的边界线上 pt.y = polygoni.y & ( (polygoni.x pt.x & pt.x polygonj.x) | (polygonj.x pt.x & pt.x polygoni.x) ) ) inside = true; break; return inside;3.角度和判别法 角度和判别法就是判定点与多边形所有相邻顶点组成的角的角度和来判断点与多边形的位置关系。如果点在多边形内部,只要该点不在边界线或者顶点上,则角度和为三百六十度。如果在边界线上,则角度和为一百八十度。如果点在多边形外部,则角度和无法达到三百六十度。但是角度和可能会达到一百八十度,比如判断点在(60,10)。代码如下:/ 根据需要不判断顶点bool IsPointInLine( const POINTD &pt,const POINTD &pt1,const POINTD &pt2 ) bool inside = false; if (pt.y = pt1.y & pt1.y = pt2.y & (pt1.x pt.x & pt.x pt2.x) | (pt2.x pt.x & pt.x pt1.x) ) inside = true; else if (pt.x = pt1.x & pt1.x = pt2.x & (pt1.y pt.y & pt.y pt2.y) | (pt2.y pt.y & pt.y pt1.y) ) inside = true; else if ( (pt1.y pt.y & pt.y pt2.y) | (pt2.y pt.y & pt.y pt1.y) & (pt1.x pt.x & pt.x pt2.x) | (pt2.x pt.x & pt.x pt1.x) ) if (0 = (pt.y-pt1.y)/(pt2.y-pt1.y)-(pt.x - pt1.x) / (pt2.x-pt1.x) inside = true; return inside;bool InsidePolygon2( POINTD *polygon,int N,POINTD p ) int i,j; double angle = 0; bool inside = false; for (i = 0,j = N - 1;i M_PI) radian = 2* M_PI - radian; angle += radian; / 计算角度和 if ( fabs(6.28318530717958647692 - angle) 1e-7 ) inside = true; return inside;4.面积和判别法根据角度和判别法,我们可以继续演化,可以得出如下结论:如果一个点在多边形内部,该点与多边形所有相邻顶点组成的三角形面积和为多边形面积。反之不成立。求三角形面积:已知三角形A(x1,y1)B(x2,y2)C(x3,y3),则面积公式为: |x1x2x3|S(A,B,C)=|y1y2y3|*0.5(当三点为逆时针时为正,顺时针则为负的) |111|=(x1*y2-x1*y3-x2*y1+x2*y3+x3*y1-x3*y2)*0.5求多边形面积:根据上面求三角形的方法,已知多边形A1A2A3.An(顺或逆时针都可以),设平面上有任意的一点P,则面积公式为:S(A1,A2,A3.An)=S(P,A1,A2)+S(P,A2,A3)+.+S(P,An,A1)既然P是可以任取,为了方便用(0,0)好了。代码如下:bool InsidePolygon3( POINTD *polygon,int N,POINTD pt ) int i,j; bool inside = false; double polygon_area = 0; double trigon_area = 0; for (i = 0,j = N - 1;i N;j = i+) polygon_area += polygoni.x * polygonj.y - polygonj.x * polygoni.y; trigon_area += abs( pt.x * polygoni.y - pt.x * polygonj.y - polygoni.x * pt.y + polygoni.x * polygonj.y + polygonj.x * pt.y - polygonj.x * polygoni.y ); trigon_area *= 0.5; polygon_area = abs(polygon_area * 0.5); if ( fabs(trigon_area - polygon_area) 1e-7 ) inside = true; return inside;5.点线判别法经网友glshader提示,添加了这个方法。如果判断点在所有边界线的同侧,就能判定该点在多边形内部。判断方法就是判断两条同起点射线斜率差。代码如下:bool InsidePolygon4( POINTD *polygon,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 鱼尾鳍的血液流动
- 济宁市2024-2025学年八年级上学期语文期末测试试卷
- 集安市2025-2026学年七年级上学期语文月考测试试卷
- 电路基础知识课件教学
- 2025年度财务人员年度考核表个人总结
- 高速车速安全知识培训课件
- 电解池和原电池课件
- 高速收费业务知识培训课件
- 电芯活化知识培训课件
- 道路园林绿化养护服务方案
- 变频及伺服应用技术(郭艳萍 钟立)全套教案课件
- 2024新译林版英语八年级上单词汉译英默写表(开学版)
- 美的集团工作流程体系
- 港口和码头基本知识培训课件
- 美容外科安全应急预案范文(3篇)
- 水利工程拦水坝建设方案实例
- (2025年标准)出资收车协议书
- 6G多维度切片QoS保障-洞察及研究
- 老年人能力评估师考试题能力模拟题及答案
- 2025-2026学年外研版(三起)(2024)小学英语四年级上册教学计划及进度表
- 2025年安徽国控集团所属企业招聘7人笔试备考题库及答案解析
评论
0/150
提交评论