zoukankan      html  css  js  c++  java
  • 计算几何——点线关系(叉积)poj2318

    #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));
            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 = 5050;
    Line line[maxn];
    int ans[maxn];
    
    int main(){
        int n,m;
        double x1,y1,x2,y2;
        bool first=1;
        while(scanf("%d",&n)==1 && n){
            if(first)first=0;
            else puts("");
            scanf("%d%lf%lf%lf%lf",&m,&x1,&y1,&x2,&y2);
            double Ui,Li;
            for(int i=0;i<n;i++){
                scanf("%lf%lf",&Ui,&Li);
                line[i]=Line(Point(Li,y2),Point(Ui,y1));
            } 
            line[n]=Line(Point(x2,y2),Point(x2,y1));
            /*for(int i=0;i<=n;i++)
                line[i].adjust();*/
            
            double x,y;
            Point p;
            memset(ans,0,sizeof ans);
            
            while(m--){
                scanf("%lf%lf",&x,&y);
                p=Point(x,y);
                int l=0,r=n,tmp=0,mid;
                while(l<=r){
                    mid=l+r>>1;
                    if(line[mid].relation(p)==1){//p在直线的左边 
                        tmp=mid;r=mid-1;
                    }
                    else l=mid+1;
                }
                ans[tmp]++;
            }
            for(int i=0;i<=n;i++)
                printf("%d: %d
    ",i,ans[i]);
        }
        return 0;
    }
  • 相关阅读:
    剑指Offer-11.二进制中1的个数(C++/Java)
    剑指Offer-10.矩形覆盖(C++/Java)
    剑指Offer-9.变态跳台阶(C++/Java)
    UVA 1608 Non-boring sequence 不无聊的序列(分治,中途相遇)
    UVA1607 Gates 与非门电路 (二分)
    UVA 1451 Average平均值 (数形结合,斜率优化)
    UVA 1471 Defense Lines 防线 (LIS变形)
    UVA 1606 Amphiphilic Carbon Molecules 两亲性分子 (极角排序或叉积,扫描法)
    UVA 11134 FabledRooks 传说中的车 (问题分解)
    UVA 1152 4 Values Whose Sum is Zero 和为0的4个值 (中途相遇)
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10920441.html
Copyright © 2011-2022 走看看