- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
判断点在多边形内外及简单算法zoj1081
惊喜发现判断点在多边形内外的超简单算法 发信站: 逸仙时空 Yat-sen Channel (Wed Mar 28 01:27:19 2007) ? ? ? 今天学图形学的时候发现了一个求多边形内外的超简单算法,当时觉得非常惊喜, 后来晚上上完选修的时候在走廊遇到bug,bug也是很惊喜地感慨道:居然有甘简单既办法 都捻唔到!遂将其写下,供大家分享,希望不会太火星。 ? ? ? 这个算法是源自《计算机图形学基础教程》(孙家广,清华大学出版社),在该书 的48-49页,名字可称为“改进的弧长法”。该算法只需O(1)的附加空间,时间复杂度为O (n),但系数很小;最大的优点是具有很高的精度,只需做乘法和减法,若针对整数坐标则 完全没有精度问题。而且实现起来也非常简单,比转角法和射线法都要好写且不易出错。 ? ? ? 首先从该收中摘抄一段弧长法的介绍:“弧长法要求多边形是有向多边形,一般规 定沿多边形的正向,边的左侧为多边形的内侧域。以被测点为圆心作单位圆,将全部有向 边向单位圆作径向投影,并计算其中单位圆上弧长的代数和。若代数和为0,则点在多边形 外部;若代数和为2π则点在多边形内部;若代数和为π,则点在多边形上。” ? ? ? 按书上的这个介绍,其实弧长法就是转角法。但它的改进方法比较厉害:将坐标原 点平移到被测点P,这个新坐标系将平面划分为4个象限,对每个多边形顶点P,只考虑 其所在的象限,然后按邻接顺序访问多边形的各个顶点P,分析P和P[i+1],有下列 三种情况: ? ? (1)P[i+1]在P的下一象限。此时弧长和加π/2; ? ? (2)P[i+1]在P的上一象限。此时弧长和减π/2; ? ? (3)P[i+1]在Pi的相对象限。首先计算f=y[i+1]*x-x[i+1]*y(叉积),若f= 0,则点在多边形上;若f0,弧长和减π;若f0,弧长和加π。 ? ? ? 最后对算出的代数和和上述的情况一样判断即可。 ? ? ? 实现的时候还有两点要注意,第一个是若P的某个坐标为0时,一律当正号处理; 第二点是若被测点和多边形的顶点重合时要特殊处理。 ? ? ? ? ? 以上就是书上讲解的内容,其实还存在一个问题。那就是当多边形的某条边在坐标 轴上而且两个顶点分别在原点的两侧时会出错。如边(3,0)-(-3,0),按以上的处理,象限 分别是第一和第二,这样会使代数和加π/2,有可能导致最后结果是被测点在多边形外。 而实际上被测点是在多边形上(该边穿过该点)。 ? ? ? 对于这点,我的处理办法是:每次算P和P[i+1]时,就计算叉积和点积,判断该 点是否在该边上,是则判断结束,否则继续上述过程。这样牺牲了时间,但保证了正确性 。 ? ? ? 具体实现的时候,由于只需知道当前点和上一点的象限位置,所以附加空间只需O( 1)。实现的时候可以把上述的“π/2”改成1,“π”改成2,这样便可以完全使用整数进 行计算。不必考虑顶点的顺序,逆时针和顺时针都可以处理,只是最后的代数和符号不同 而已。整个算法编写起来非常容易。 ? ? ? 针对以上算法,我写了一个代码,拿ZOJ 1081 Points Within进行测试,顺利Acce pted。这证明该算法的正确性还是可以保障的。 ? ? 以下附上我的代码: // ZOJ 1081 , 改进弧长法判点在形内形外 #include stdio.h #include math.h const int MAX = 101 ; struct point { int x , y ; } p[MAX] ; int main() { ? ? ? ? int n , m , i , sum , t1 , t2 , f , prob = 0 ; ? ? ? ? point t ; ? ? ? ? while ( scanf( %d , n ) , n ) ? ? ? ? { ? ? ? ? ? ? ? ? if( prob ++ ) printf ( \n ); ? ? ? ? ? ? ? ? printf ( Problem %d:\n , prob ) ; ? ? ? ? ? ? ? ? scanf ( %d , m ) ; ? ? ? ? ? ? ? ? for ( i = 0 ; i n ; i ++ ) scanf ( %d%d , p.x , p. y ) ; ? ? ? ? ? ? ? ? p[n] = p[0] ; ? ? ? ? ? ? ? ? while ( m -- ) ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? ?
文档评论(0)