计算几何——点线关系(叉积)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的主要内容,如果未能解决你的问题,请参考以下文章