关键词不能为空

当前您在: 主页 > 英语 >

判断点在多边形内的多种写法

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2021-02-01 22:07
tags:

-

2021年2月1日发(作者:阳线)


判断点在多边形内的多种写法


(


射线算法


)




(2010-10-09 17:04:24)





标签:



计算几何




射线法




杂谈





分类:



经验总结



************ *******************************


*


射线算法一


*


*******************************************


1.


已知点


poi nt(x,y)


和多边形


Polygon



x1,y1;x2,y2;….xn,yn;


);



2.


< br>point


为起点,以无穷远为终点作平行于


X


轴的直线


line(


x,y; -



,y)




3.



循环取得


(for(i=0;i


多边形的每一条边


side


(xi,yi;xi+1,yi+1)



且判断是否平行于


X


轴,如果平行< /p>


continue


,否则,


i++




4.


同时判断


point(x,y)


是否在


side


上,如果是,则返回


1(

点在多边形




)


,否则继续下面的判断;



5. < /p>


判断线


side



line


是否有交点,如果有则


count++


,否则,


i++




6.


判断交点的总数,如果为奇数则返回< /p>


0


(点在多边形内),偶数则返回


2


(点在多边


形外)。





代码:




const double INFINITY = 1e10;


const double ESP = 1e-5;


const int MAX_N = 1000;



struct Point


{


double x, y;


};


struct LineSegment


{


Point pt1, pt2;


};


typedef vector Polygon;



//


计算叉乘


|P0P1| ×


|P0P2|


double Multiply(Point p1, Point p2, Point p0)


{


return ( (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y) );


}


//


判断线段是否包含点


point


bool IsOnline(Point point, LineSegment line)


{


return( ( fabs(Multiply(1, 2, point)) < ESP ) &&


( ( point.x - 1.x ) * ( point.x - 2.x ) <= 0 ) &&


( ( point.y - 1.y ) * ( point.y - 2.y ) <= 0 ) );


}


//


判断线段相交



bool Intersect(LineSegment L1, LineSegment L2)


{


return( (max(1.x, 2.x) >= min(1.x, 2.x)) &&


(max(1.x, 2.x) >= min(1.x, 2.x)) &&


(max(1.y, 2.y) >= min(1.y, 2.y)) &&


(max(1.y, 2.y) >= min(1.y, 2.y)) &&


(Multiply(1, 2, 1) * Multiply(2, 2, 1) >= 0) &&


(Multiply(1, 2, 1) * Multiply(2, 2, 1) >= 0) );


}


//


判断点在多边形内



bool InPolygon(const Polygon& polygon, Point point)


{


int n = ();


int count = 0;


LineSegment line;


1 = point;


2.y = point.y;


2.x = - INFINITY;



for( int i = 0; i < n; i++ )


{


//


得到多边形的一条边



LineSegment side;


1 = polygon[i];


2 = polygon[(i + 1) % n];



if( IsOnline(point, side) )


{


return1


}



//


如果

< br>side


平行


x


轴则不作考虑< /p>



if( fabs(1.y - 2.y) < ESP )


{


continue;


}



if( IsOnline(1, line) )


{


if( 1.y > 2.y ) count++;


}


else if( IsOnline(2, line) )


{


if( 2.y > 1.y ) count++;


}


else if( Intersect(line, side) )


{


count++;


}


}



if ( count % 2 == 1 ) {return 0;}


else { return 2;}


}


}


**** ***************************************


*


射线算法二


*


******************************************* < /p>


本文是采用射线法判断点是否在多边形内的


C

语言程序。多年前,我自己实现了这样一个


算法。但是随着时间的推移,我决定重写 这个代码。参考周培德的《计算几何》一书,结合


我的实践和经验,我相信,在这个算法 的实现上,这是你迄今为止遇到的最优的代码。



这是个


C


语言的小算法的实现程序,本来不想放到这里。可是,当我自己要实 现这样一个


算法的时候,


想在网上找个现成的,


考察下来竟然一个符合需要的也没有。


我对自己大学读


书时写的代码没有信心,所以,决定重新写一个,并把它放到这里,以飨读者。也增加一下


BLOG


的点击量。



首先定义点结构如下:



以下是引用片段:




typedef struct


{


double x, y;


} vertex_t;



本算法里所指的多边形,


是指由一系 列点序列组成的封闭简单多边形。


它的首尾点可以是或


不是同一 个点(不强制要求首尾点是同一个点)。


这样的多边形可以是任意形状的,包括多


条边在一条绝对直线上。因此,定义多边形结构如下:



以下是引用片段:




typedef struct


{


int num_vertices;


vertex_t *vertex;


} vertexlist_t;


为加快 判别速度,首先计算多边形的外包矩形(


rect_t


),判断 点是否落在外包矩形内,只


有满足落在外包矩形内的条件的点,才进入下一步的计算。为 此,引入外包矩形结构


rect_t


和求点集合的外包矩形内的 方法


vertices_get_extent


,代码如下:< /p>



以下是引用片段:




typedef struct


{


double min_x, min_y, max_x, max_y;


} rect_t;



void vertices_get_extent (const vertex_t* vl, int np,


rect_t* rc )


{


int i;


if (np > 0){


rc->min_x = rc->max_x = vl[0].x; rc->min_y = rc->max_y = vl[0].y;


}else{


rc->min_x = rc->min_y = rc->max_x = rc->max_y = 0;


}


for(i=1; i


{


if(vl[i].x < rc->min_x) rc->min_x = vl[i].x;


if(vl[i].y < rc->min_y) rc->min_y = vl[i].y;


if(vl[i].x > rc->max_x) rc->max_x = vl[i].x;


if(vl[i].y > rc->max_y) rc->max_y = vl[i].y;


}


}


当点满足落在多边形外包矩形内的条件,


要进一步判断点



v



是否在多边形



vl



np



内。


本程序采用射线法,由待测试点(


v


)水平引出一条射线


B

< br>(


v



w


),计算


B



vl

< br>边线的


交点数目,记为


c


,根据 奇内偶外原则(


c


为奇数说明


v



vl


内,否则


v< /p>


不在


vl


内)判断点

是否在多边形内。



具体原理就不多说。为计算线段间是否 存在交点,引入下面的函数:




1< /p>



is_same


判断

< br>2



p



q


)个点是(


1


)否(


0


)在直线


l


< p>
l_start



l_end

)的同侧;




2



is_intersect


用来判断


2


条线段(不是直线)


s1



s2


是(


1


) 否(


0


)相交;



以下是引用


片段:




static int is_same(const vertex_t* l_start, const vertex_t* l_end,


const vertex_t* p,


const vertex_t* q)


{


double dx = l_end->x - l_start->x;


double dy = l_end->y - l_start->y;


double dx1= p->x - l_start->x;


double dy1= p->y - l_start->y;


double dx2= q->x - l_end->x;


double dy2= q->y - l_end->y;


return ((dx*dy1-dy*dx1)*(dx*dy2-dy*dx2) > 0? 1 : 0);


}



static int is_intersect(const vertex_t* s1_start, const vertex_t* s1_end,


const vertex_t* s2_start, const vertex_t* s2_end)


{


return (is_same(s1_start, s1_end, s2_start, s2_end)==0 &&


is_same(s2_start, s2_end, s1_start, s1_end)==0)? 1: 0;


}



下面的函数


pt_in_poly


就是判断点(


v


)是(


1


)否(


0


)在多边形(


vl

< br>:


np


)内的程序:




下是引用片段:



int pt_in_poly ( const vertex_t* vl, int np,


const vertex_t* v)


{


int i, j, k1, k2, c;


rect_t rc;


vertex_t w;


if (np < 3)


return 0;


vertices_get_extent(vl, np, &rc);


if (v->x < _x || v->x > _x || v->y < _y || v->y > _y)


return 0;



w.x = _x + DBL_EPSILON;


w.y = v->y;


c = 0;


for(i=0; i


{


j = (i+1) % np;


if(is_intersect(vl+i, vl+j, v, &w))


{


C++;


}


else if(vl[i].y==w.y)


{


k1 = (np+i-1)%np;


while(k1!=i && vl[k1].y==w.y)


k1 = (np+k1-1)%np;


k2 = (i+1)%np;


while(k2!=i && vl[k2].y==w.y)


k2 = (k2+1)%np;


if(k1 != k2 && is_same(v, &w, vl+k1, vl+k2)==0)


c++;


if(k2 <= i)


break;


i = k2;


}


}


return c%2;


}






判断点在多边形内的多种写法


(


射线算法< /p>


)




(2010-10-09 17:04:24)





标签:



计算几何




射线法




杂谈





分类:



经验总结



************ *******************************


*


射线算法一


*


*******************************************


1.


已知点


poi nt(x,y)


和多边形


Polygon



x1,y1;x2,y2;….xn,yn;


);



2.


< br>point


为起点,以无穷远为终点作平行于


X


轴的直线


line(


x,y; -



,y)




3.



循环取得


(for(i=0;i


多边形的每一条边


side


(xi,yi;xi+1,yi+1)



且判断是否平行于


X


轴,如果平行< /p>


continue


,否则,


i++




4.


同时判断


point(x,y)


是否在


side


上,如果是,则返回


1(

点在多边形




)


,否则继续下面的判断;



5. < /p>


判断线


side



line


是否有交点,如果有则


count++


,否则,


i++




6.


判断交点的总数,如果为奇数则返回< /p>


0


(点在多边形内),偶数则返回


2


(点在多边


形外)。


-


-


-


-


-


-


-


-



本文更新与2021-02-01 22:07,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/595431.html

判断点在多边形内的多种写法的相关文章

  • 爱心与尊严的高中作文题库

    1.关于爱心和尊严的作文八百字 我们不必怀疑富翁的捐助,毕竟普施爱心,善莫大焉,它是一 种美;我们也不必指责苛求受捐者的冷漠的拒绝,因为人总是有尊 严的,这也是一种美。

    小学作文
  • 爱心与尊严高中作文题库

    1.关于爱心和尊严的作文八百字 我们不必怀疑富翁的捐助,毕竟普施爱心,善莫大焉,它是一 种美;我们也不必指责苛求受捐者的冷漠的拒绝,因为人总是有尊 严的,这也是一种美。

    小学作文
  • 爱心与尊重的作文题库

    1.作文关爱与尊重议论文 如果说没有爱就没有教育的话,那么离开了尊重同样也谈不上教育。 因为每一位孩子都渴望得到他人的尊重,尤其是教师的尊重。可是在现实生活中,不时会有

    小学作文
  • 爱心责任100字作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文
  • 爱心责任心的作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文
  • 爱心责任作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文