UVA 634 || Polygon(转角法,点在凸包内

题目大意:T when P belongs to the polygon or F otherwise 

如果点P属于多边形那么输出T,反之输出F。


刚刚入门计算几何。都是自己摸索出来的,如果理解有偏差,望指点。


转角法。

UVA 634 || Polygon(转角法,点在凸包内_第1张图片

我们把多边形每条边的转角加起来,如果是2pi,那么点在多边形内。

如果是Ipi,那么点在多边形的边界上。

如果是0,那么点在多边形外部。

如上图图一 转角为

图二转角为


转角法的代码实现为假设一条向右的射线。统计多边形穿过这条射线正反多少次。

逆时针加1,顺时针减1。


红色字体为大白上面的原话,我琢磨了一个下午一直卡壳。。

然后终于有了自己的见解。


例如题目的第二个例子。

具体看代码,图片已经附上帮组理解。

UVA 634 || Polygon(转角法,点在凸包内_第2张图片

UVA 634 || Polygon(转角法,点在凸包内_第3张图片

#include
#include
#include
#define FOR(i,m,n) for( int i = m; i  点p属于线段ab
    */

}
int ispointinpoly(int n)
{
    int wn =0;// wingding number
    FOR(i,0,n)
    {
        if(onsegment(p,point[i],point[i+1]) )return -1;//onsegment
        int k = dcmp( cross(point[i],point[i+1],p ) );
        int d1 = dcmp(point[i].y - p.y);
        int d2 = dcmp(point[i+1].y - p.y);
        //printf("      i=%2d    k=%2d d1=%2d d2=%2d  ",i,k,d1,d2)
        
        //p点引出一条向右的射线
        if( k >0 && d1<=0 && d2>0)wn++;//射线逆时针穿过 i到i+1这两点间的线段 wn加一
        if( k <0 && d2<=0 && d1>0)wn--;//顺时针则减一
        //printf("wn=%2d\n",wn);n

    }
    if( wn!= 0)return 1;//indise
    return 0;//outside
}
int main()
{
    int n;
    while( cin>>n && n )
    {
        FOR(i,0,n)
        {
            scanf("%lf %lf",&point[i].x,&point[i].y);
        }
        point[n] = point[0];//point[i+1]
        cin>>p.x>>p.y;
        if( ispointinpoly(n)==0 )puts("F");
        else puts("T");
    }
    return 0;
}


你可能感兴趣的:(计算几何)