• 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"<<'
    ';
                
            }
        }
    }
    
  • 相关阅读:
    js 抓取距离的方法
    mysql 设置账户权限
    mysql 主从复制
    mysql 分区
    linux 安装samba
    linux 配置lamp
    linux 本地虚拟机配置
    linux 权限
    linux 磁盘分区
    mysql-进阶 if/while/case
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366474.html
Copyright © 2020-2023  润新知