计算几何模板 更新中
今天又切了一题,做题的同时当然也验证了各种模板
每次都感觉有所改进
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <math.h>
#include <cstdio>
#include<algorithm>
using namespace std;
const int maxn = 100010;
const double eps = 1e-8;
inline int max(int x,int y){return x>y?x:y;}
inline double max(double x,double y) {return x>y?x:y;}
inline double min(double a,double b){ return a<b?a:b;}
inline double sgn(double x) {return fabs(x)<eps?0:(x>0?1:-1);}
struct point{
double x,y;
point operator + (const point& t) const {
point tmp;
tmp.x = x + t.x;
tmp.y = y + t.y;
return tmp;
}
point operator - (const point& t) const {
point tmp;
tmp.x = x - t.x;
tmp.y = y - t.y;
return tmp;
}
bool operator < (const point &p) const {
return sgn(x-p.x)<0 || sgn(x-p.x)==0 && sgn(y-p.y)<0;
}
bool operator == (const point& t) const {
return sgn(x-t.x)==0 && sgn(y-t.y)==0;
}
}p[maxn],set[maxn];
struct Seg{point s,e;};
struct Line { double a, b, c;};
inline double dist(point a,point b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
bool cmp(point a,point b) {return (a.x<b.x || fabs(a.x-b.x)<eps && a.y<b.y);}
inline double cross(point a,point b,point c){return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);}
bool chonghe(point a,point b,point c,point d){return !sgn(cross(a,b,c)) && !sgn(cross(a,b,d));}//判断线段共线,即直线与线段共线
bool Inter(point a,point b,point c,point d){return sgn(cross(a,b,c))*sgn(cross(a,b,d))<=0;}//判断a,b直线是否与c,d线段相交
bool dotOnSeg(point p, point s, point e) {
if ( p == s || p == e ) return true;
return sgn(cross(s,e,p))==0 && sgn((p.x-s.x)*(p.x-e.x))<=0 && sgn((p.y-s.y)*(p.y-e.y))<=0;
}
Line Turn(point s, point e) {
Line ln;
ln.a =s.y - e.y ;
ln.b =e.x - s.x;
ln.c =s.x*e.y - e.x*s.y;
return ln;
}
bool Intersect(point p1, point p2, point p3, point p4, point& p) {
double a1, b1, c1, a2, b2, c2, d;
a1 = p1.y - p2.y; b1 = p2.x - p1.x; c1 = p1.x*p2.y - p2.x*p1.y;
a2 = p3.y - p4.y; b2 = p4.x - p3.x; c2 = p3.x*p4.y - p4.x*p3.y;
d = a1*b2 - a2*b1;
if ( fabs(d) < eps ) return false;
p.x = (-c1*b2 + c2*b1) / d;
p.y = (-a1*c2 + a2*c1) / d;
return true;
}
bool point_in_polygon(point o, point* p, int n) {
int i, t;
point a, b;
p[n] = p[0]; t = 0;
for (i=0; i < n; i++) {
if ( dotOnSeg(o, p[i], p[i+1]) ) return true;
a = p[i]; b = p[i+1];
if ( a.y > b.y ) {
point tmp = a; a = b; b = tmp;
}
if ( cross(o, a, b) < -eps && a.y < o.y-eps && o.y < b.y+eps )
t++;
}
return t&1;
}
bool Seg_Inst(Seg s1, Seg s2, point &p) {//判断线段相交,共线时需要特判,先判直线相交,再判点在直线上
Line l1=Turn(s1.s,s1.e),l2=Turn(s2.s,s2.e);
double d = l1.a*l2.b - l2.a*l1.b;
if ( sgn(d) ==0 ) return false;
p.x = (-l1.c*l2.b + l2.c*l1.b) / d;
p.y = (-l1.a*l2.c + l2.a*l1.c) / d;
return dotOnSeg(p,s1.s,s1.e) && dotOnSeg(p,s2.s,s2.e);
}
bool check(Seg s1, Seg s2, point& pp) {//共线,特判
if ( s1.s==s2.s || s1.s==s2.e ) { pp = s1.s; return true;}
if ( s1.e==s2.s || s1.e==s2.e) {pp = s1.e;return true;}
return false;
}
点线距离
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
inline double PPdis(Point a,Point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } inline double PLdis(Point a,Point l1,Point l2){ return fabs(Cross(a,l1,l2)/PPdis(l1,l2)); }
是否是凸多边形
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
inline int _sgn(double x){return fabs(x) < eps ? 0 : (x > 0 ? 1 : 2);} int is_convex(int n,Point P[]){//允许相邻边共线,顶点按顺时针或者逆时针给出 int i,s[3]={1,1,1}; for(i=0;i<n&&s[1]|s[2];i++) s[_sgn(Cross(P[i],P[(i+1)%n],P[(i+2)%n]))]=0; return s[1]|s[2]; }
点是否在凸多边形内或边上
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
int inside_convex(Point q,int n,Point *p){ int i,s[3]={1,1,1}; for(i=0;i<n&&s[1]|s[2];i++) s[_sgn(Cross(p[i],p[(i+1)%n],q))]=0; return s[1]|s[2]; }
点在任意多边形内或边上
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <math.h> #include <cstdio> #include<algorithm> using namespace std; const int maxn = 100010; const double eps = 1e-8; inline double sgn(double x) {return fabs(x)<eps?0:(x>0?1:-1);} struct point{ double x,y; bool operator == (const point& t) const { return sgn(x-t.x)==0 && sgn(y-t.y)==0; } }p[maxn],set[maxn]; inline double cross(point a,point b,point c){return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);} bool dotOnSeg(point p, point s, point e) { if ( p == s || p == e ) return true; return sgn(cross(s,e,p))==0 && sgn((p.x-s.x)*(p.x-e.x))<=0 && sgn((p.y-s.y)*(p.y-e.y))<=0; } bool point_in_polygon(point o, point* p, int n) { int i, t; point a, b; p[n] = p[0]; t = 0; for (i=0; i < n; i++) { if ( dotOnSeg(o, p[i], p[i+1]) ) return true; a = p[i]; b = p[i+1]; if ( a.y > b.y ) { point tmp = a; a = b; b = tmp; } if ( cross(o, a, b) < -eps && a.y < o.y-eps && o.y < b.y+eps ) t++; } return t&1; }