ZOJ1081(射线法判断点是否在多边形内部)

通往快乐老家的路

射线法判是否在多边形内部的板子吧

射线法:过该点做一条平行于x轴的射线 ,若该与多边形有奇数个交点,则该点在多边形内部

这可以转化为求改点与多边形的每一条边是否有交点

但要注意一些特殊情况,比如交点时多边形的顶点,这时我们需要规定交在边的下端点 统计进答案或是交在边的上端点统计进答案

(也就是保证一个点要么都被统计要么都不被统 计)。

详解代码

#include<bits/stdc++.h>
using namespace std;
int n,m;
inline int read(){
    char ch=getchar();
    int res=0,f=1;
    while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
    return res*f;
}
struct point{
    int x,y;
    point(){}
    point(int a,int b):
        x(a),y(b){}
    friend inline point operator -(const point &a,const point &b){//重载运算符 
        return point(b.x-a.x,b.y-a.y);
    }
    friend inline int operator *(const point &a,const point &b){
        return a.x*b.y-a.y*b.x;
    }
    friend inline int dot(const point &a,const point &b){//点积 
        return a.x*b.x+a.y*b.y;    
    }
}f,p[105];
inline bool check(const point &a,const point &b,const point &c){//判断共线的情况 (三点共线且被判定的点在线段中间) 
    int d=(a-c)*(b-c);
    if(d!=0) return false;//如果差积不为0,则三点不共线 
    int fk=dot(a-c,b-c);
    return fk<=0;//如果点积大于0,则被判定的点不在线段中间 
}
inline int area(){//求多边形的面积 
    int ans=0;
    for(int i=0;i<n;i++){
        ans+=p[i]*p[i+1];
    }
    return ans;
}
inline bool init(point q){
    int num=0;
    for(int i=0;i<n;i++){//枚举找相交的边 
        if(check(p[i],p[i+1],q)) return true;//如果在线段之间则满足 
        int f1=p[i].y-q.y,f2=p[i+1].y-q.y;
        int det=(p[i]-q)*(p[i+1]-q);
        if((det>=0&&f1<0&&f2>=0)||(det<=0&&f1>=0&&f2<0)) num++;//这里默认的是做一条平行于x轴的射线,并判断有没有交点 
    }
    return num&1;//相交的边数是否为奇数 
}
int main(){
    for(int T=1;;T++){
        n=read();
        if(n==0) break;
        m=read();
        for(int i=0;i<n;i++){
            p[i].x=read(),p[i].y=read();
        }
        p[n]=p[0];
        if(T!=1){
            cout<<'
';
        }
        cout<<"Problem "<<T<<":"<<'
';
        for(int i=1;i<=m;i++){
            f.x=read(),f.y=read();    
            if(init(f)) cout<<"Within"<<'
';
            else cout<<"Outside"<<'
';
            
        }
    }
}
原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366474.html