• 射线法


    射线法

    这是一个大佬看了都说简单的算法。。。。(甚至觉得没有掌握的必要)

    QAQ

    这个算法是用来判断一个点是否在一个多边形以内。很简单 将这个点沿着x轴的正方向作射线。如果穿过的边数为基数,那么这个点在多边形内;反之不在。

    由于有可能出现经过两条边的相邻的点,而被重复计算的情况。我们只需要采用上加下不加策略,即如果射线经过了这条边的上顶点,则cnt++,如果经过下顶点,则不变。经过这条边上除了上顶点和下顶点的地方,cnt++。正确性显然。

    另外因为我们需要将每条边都遍历完。而我们只向 x的正方向做了射线,那么完全在询问点的左边的边不能计算。可是每条边都遍历,难道不会计算吗?

    不!不会计算。自己去手动模拟一下条件,当其在左边的时候,康康是否被重复计算了呢(没有)

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int maxn=1e6;
    int n,m;
    struct point{
    	double x,y;
    	point(){x=0,y=0;}
    	point(double a,double b){x=a,y=b;}
    	point operator+(const point &b)const{return point(x+b.x,y+b.y);}
    	point operator-(const point &b)const{return point(x-b.x,y-b.y);}
    	point operator*(const double &b)const{return point(x*b,y*b);}
    	double operator*(const point &b)const{return x*b.y-y*b.x;}
    	double dot()const{return x*x+y*y;}
    	double dot(const point &b)const{return x*b.x+y*b.y;}
    };
    point p[maxn];
    inline double cross(const point &a,const point &b){return a.x*b.y-a.y*b.x;}
    inline double d(const point &a,const point &b){return sqrt((a-b).dot());}
    inline bool check(const point &a,const point &b,const point &c){
    	if(fabs(d(a,c)+d(b,c)-d(a,b))==0) return true;
    	return false;
    } 
    inline double area(){
    	double sum=0;
    	for(int i=0;i<n;i++) sum+=cross(p[i],p[i+1]);
    	return sum;
    }
    void init(){
    	for(int i=0;i<n;i++){
    		scanf("%lf %lf",&p[i].x,&p[i].y);
    	}
    	p[n]=p[0];
    //	if(area()<0) reverse(p,p+n);
    	p[n]=p[0];
    }
    int main(){
    	for(int test=1;;test++){
    		scanf("%d",&n);if(n==0) break;
    //		scanf("%d",&m);
    		init();
    //		if(test!=1) printf("
    ");
    //		printf("Problem %d:
    ",test);
    //		while(m--){
    			int cnt=0;
    			point q;
    			scanf("%lf %lf",&q.x,&q.y);			
    			for(int i=1;i<=n;i++){
    				if(check(p[i-1],p[i],q)){printf("T
    ");break;}
    				double height1=p[i-1].y-q.y,height2=p[i].y-q.y;
    				double cro=cross((p[i-1]-q),(p[i]-q));
    				if((cro>=0 && height1<0 && height2>=0) || (cro<=0 && height1>=0 && height2<0)) cnt++;
    			}
    			if(cnt&1) printf("T
    ");
    			else printf("F
    ");
    //		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    13-7实现旅拍卡片布局-2
    13-6实现旅拍卡片布局-1
    13-5实现旅拍瀑布流布局-2
    13-4实现旅拍瀑布流布局-1
    13-3使用TabBar+TabBarView 实现旅拍可滑动切换多Tab
    13-2根据接口实现dao层
    13-1
    12-12本章小结
    12-11【锦上添花】Flutter AI只能语音搜索功能实现
    12-10【收货果实】Futter AI只能语音界面开发-2
  • 原文地址:https://www.cnblogs.com/mendessy/p/12109816.html
Copyright © 2020-2023  润新知