zoukankan      html  css  js  c++  java
  • 计算几何——线段和直线判交点poj3304

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    
    const double esp = 1e-8;
    const double inf = 1e20;
    const double pi = acos(-1.0);
    const int maxp = 1010;
    
    int sgn(double x){
        if(fabs(x) < esp)return 0;
        if(x < 0)return -1;
        else return 1;
    } 
    inline double sqr(double x){return x*x;}
        
    struct Point{
        double x,y;
        Point(){}
        Point(double _x,double _y):x(_x),y(_y){}
        void input(){scanf("%lf%lf",&x,&y);}
        void output(){printf("%.2lf %.2lf
    ",x,y);}
        bool operator==(Point b)const {
            return sgn(x-b.x)==0 && sgn(y-b.y)==0;    
        }
        bool operator < (Point b)const {//判左下 
            if( sgn(x-b.x)==0 )  //横坐标相等 
                return sgn(y-b.y)<0;
            return x<b.x; 
        }
        Point operator - (const Point &b)const {
            return Point(x-b.x,y-b.y);
        }
        double operator ^(const Point &b)const {
            return x*b.y-y*b.x;
        } 
        double operator *(const Point &b)const {
            return x*b.x+y*b.y;
        }
        double len(){
            return hypot(x,y);
        }
        double len2(){
            return x*x+y*y;
        }
        double distance(Point p){
            return hypot(x-p.x,y-p.y);
        }
        Point operator +(const Point &b)const {
            return Point(x+b.x,y+b.y);
        }
        Point operator *(const double &k)const {
            return Point(x*k,y*k);
        }
        Point operator /(const double &k)const {
            return Point(x/k,y/k);
        }
        double rad(Point a,Point b){
            Point p=*this;
            return fabs(atan2( fabs((a-p)^(b-p)),(a-p)*(b-p) ));
        }
        Point trunc(double r){
            double l=len();
            if(!sgn(l))return *this;
            r/=l;
            return Point(x*r,y*r);
        }
        Point rotleft(){
            return Point(-y,x);
        }
        Point rotright(){
            return Point(y,-x);
        }
        Point rotate(Point p,double angle){
            Point v=(*this)-p;
            double c=cos(angle),s=sin(angle);
            return Point(p.x+v.x*c-v.y*s, p.y+v.x*s+v.y*c);
        }
    };
    struct Line{
        Point s,e;
        Line(){}
        Line(Point s,Point e):s(s),e(e){}
        bool operator ==(Line v){
            return (s==v.s) && (e==v.e);
        }
        Line(Point p,double angle){
            s=p;
            if(sgn(angle-pi/2)==0)
                e=s+Point(0,1);
            else e=s+Point(1,tan(angle));
        }
        Line(double a,double b,double c){
            if(sgn(a)==0){
                s=Point(0,-c/b);
                e=Point(1,-c/b);
            }
            else if(sgn(b)==0){
                s=Point(-c/a,0);
                e=Point(-c/a,1);
            }
            else {
                s=Point(0,-c/b);
                e=Point(1,(-c-a)/b);
            }
        }
        void input(){
            s.input();
            e.input();
        }
        void adjust(){
            if(e<s)swap(e,s);
        }
        double length(){
            return s.distance(e);
        }
        double angle(){
            double k=atan2(e.y-s.y,e.x-s.x);
            if(sgn(k)<0)k+=pi;
            if(sgn(k-pi)==0) k-=pi;
            return k;
        }
        int relation(Point p){
            int c=sgn((p-s)^(e-s));
            if(c<0)return 1;
            else if(c>0)return 2;
            else return 3;
        }
        bool pointonseg(Point p){
            return sgn((p-s)^(e-s))==0 && sgn((p-s)*(p-e))<=0;
        }
        bool parallel(Line v){
            return sgn((e-s)^(v.e-v.s))==0;
        }
        int segcrossseg(Line v){
            int d1=sgn((e-s)^(v.s-s));
            int d2=sgn((e-s)^(v.e-s));
            int d3=sgn((v.e-v.s)^(s-v.s));
            int d4=sgn((v.e-v.s)^(e-v.s));
            if( (d1^d2)==-2 && (d3^d4)==-2) return 2;
            return (d1==0 && sgn((v.s-s)*(v.s-e))<=0) ||
                (d2==0 && sgn((v.e-s)*(v.e-e))<=0) || 
                (d3==0 && sgn((s-v.s)^(s-v.e))<=0) || 
                (d4==0 && sgn((e-v.s)^(e-v.e))<=0);
        }
        int linecrossseg(Line v){
            int d1=sgn((e-s)^(v.s-s));
            int d2=sgn((e-s)^(v.e-s));
    //cout<<(d1^d2)<<'
    ';
            if((d1^d2)==-2)return 2;
            return d1==0 || d2==0;
        }
        int linecrossline(Line v){
            if((*this).parallel(v))
                return v.relation(s)==3;
            return 2;
        }
        Point crosspoint(Line v){
            double a1=(v.e-v.s)^(s-v.s);//面积 
            double a2=(v.e-v.s)^(e-v.s);
            return Point((s.x*a2-e.x*a1)/(a2-a1),
                            (s.y*a2-e.y*a1)/(a2-a1));
        }
        double dispointtoline(Point p){
            return fabs((p-s)^(e-s))/length();
        }
        double dispointtoseg(Point p){
            if(sgn((p-s)*(e-s))<0 || sgn((p-e)*(s-e))<0)
                return min(p.distance(s),p.distance(e));
            return dispointtoline(p);
        }
        double dissegtoseg(Line v){
            return min(min(dispointtoseg(v.s),dispointtoseg(v.e)),
                        min(v.dispointtoline(s),v.dispointtoline(e)));
        }
        Point lineprog(Point p){//s+vt
            return s+( ((e-s)*((e-s)*(p-s)))/(e-s).len2() );
        }
        Point symmetrypoint(Point p){
            Point q=lineprog(p);
            return Point(2*q.x-p.x,2*q.y-p.y);
        }
    };
    
    //判断是否有一条直线,和所有线段都有交点 
    const int maxn = 500;
    Line line[maxn];
    Point p[maxn]; 
    int n;
    
    int check(Line l){
        if(l.s==l.e)return 0;
        for(int i=0;i<n;i++)
            if(l.linecrossseg(line[i])==0)return 0;
        return 1;
    }
    
    int main(){
        int t;
        cin>>t;
        while(t--){
            cin>>n;
            for(int i=0;i<n;i++){
                double x1,y1,x2,y2;  
                cin>>x1>>y1>>x2>>y2;
                line[i]=Line(Point(x1,y1),Point(x2,y2)); 
            }
             
            int flag=0;
            for(int i=0;i<n;i++)
                for(int j=0;j<n;j++)
                    if(!flag){
                        Line line1=Line(line[i].s,line[j].s);
                        Line line2=Line(line[i].s,line[j].e);
                        Line line3=Line(line[i].e,line[j].s);
                        Line line4=Line(line[i].e,line[j].e);
                        if(check(line1) || check(line2) || 
                            check(line3) || check(line4)){
                                flag=1;
                            }
                    }
            if(flag)puts("Yes!");
            else puts("No!");        
        }
    }
  • 相关阅读:
    梯度下降法以及实现
    常见的端口号及其用途
    vue build报copy-webpack-plugin] unable to locate异常的解决方法
    vue build错误异常的解决方法
    Websocket-Sharp获取客户端IP地址和端口号
    理解SignalR
    城市经纬度 json
    FFmpeg部署及相关指令操作说明
    C#中Skip和Take的用法
    SQL Server 2008R2 :远程调用失败 的解决方法(全部方法)
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10920689.html
Copyright © 2011-2022 走看看