1 .判断点在多边形内外的简单算法 -- 改进弧长法 今天学图形学的时候发现了一个求多边形内外的超简单算法,当时觉得非常惊喜,后来晚上上完选修的时候在走廊遇到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,则点在多边形上;若 f<0,弧长和减 π ;若 f>0,弧长和加 π 。 最后对算出的代数和和上述的情况一样判断即可。 实现的时候还有两点要注意,第一个是若 P的某个坐标为0时,一律当正号处理;第二点是若被测点和多边形的顶点重合时要特殊处理。 以上就是书上讲解的内容,其实还存在一个问题。那就是当多边形的某条边在坐标轴上而且两个顶点分别在原点的两侧时会出错。如边(3,0)-(-3,0),按以上的处理,象限分别是第一和第二,这样会使代数和加 π /2,有可能导致最后结果是被测点在多边形外。而实际上被测点是在多边形上(该边穿过该点)。 对于这点,我的处理办法是:每次算P和 P[i+1]时,就计算叉积和点积,判断该点是否在该边上,是则判断结束,否则继续上述过程。这样牺牲了时间,但保证了正确性。 具体实现的时候,由于只需知道当前点和上一点的象限位置...