计算几何——点线关系(叉积)poj2318

Posted zsben991126

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了计算几何——点线关系(叉积)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\n",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\n",i,ans[i]);
    }
    return 0;
}

 

以上是关于计算几何——点线关系(叉积)poj2318的主要内容,如果未能解决你的问题,请参考以下文章

POJ 2318 TOYS (计算几何)叉积的运用

POJ2318 TOYS (计算几何)

POJ 2318/2398 叉积性质

计算几何专题

计算几何专题

POJ 2318 TOYS(点与直线的关系 叉积&&二分)