1. 程式人生 > >淺談計算幾何的模板集合

淺談計算幾何的模板集合

管用!

程式碼

壓縮了的

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
const int eps=1e-10;
const double PI=acos(double(-1));
struct Point 
{
    double x,y;
    double len() {return sqrt(x*x+y*y);}
    Point(double
_=.0,double __=.0):x(_),y(__) {}//生成點 double ang() {return atan2(y,x);} }//點 Point operator +(const Point &r,const Point &s) {return Point(r.x+s.x,r.y+s.y);} Point operator -(const Point &r,const Point &s) {return Point(r.x-s.x,r.y-s.y);} Point operator *(const Point &r,double
s) {return Point(r.x*s,r.y*s);} Point operator /(const Point &r,double s) {return Point(r.x/s,r.y/s);}//基本運算 int sign(double a) {return (a>eps)?1:(a<-eps)?-1:0;}//判斷正負 double dot(const Point &r, const Point &s) {return r.x*s.x+r.y*s.y;}//點積 double cross(const Point &r, const Point &s) {return
r.x*s.y-r.y*s.x;}//叉積 double ang(const Point &a) {return atan2(a.y,a.x);}//注意是反的! struct Line { Point p; Point u; double ang; Line(){} Line(Point p, Point u):p(p),u(u),ang(u.ang()){} };//線 bool operator <(const Line &r,const Line &s) {return r.ang<s.ang;} bool operator ==(const Line &r, const Line &s) {return sign(r.ang-s.ang)==0;} bool onleft(const Point &a, const Point &b, const Point &p) {return cross(b-a,p-a)>0;} bool onleft(const Line &l,const Point &p) {return cross(l.u,p-l.p)>0;} Point line_intersect(Point P, Point u, Point Q, Point v) { Point w=P-Q; double t=cross(v,w)/cross(u,v); return P+u*t; }//直線求交 Point line_intersect (const Line &a, const Line &b) {return line_intersect (a.p,a.u,b.p,b.u);} int half_plane_intersect(vector<Line> &h) { sort(h.begin(),h.end()); int n=(int)h.size(); int first,last; Point *p=new Point[n]; Line *q=new Line[n]; q[first=last=0]=h[0]; for (int i=1;i<n;i++) { while(first<last&&!onleft(h[i],p[last-1])) last--; while(first<last&&!onleft(h[i],p[first])) first++; q[++last]=h[i]; if (fabs(cross(q[last].u,q[last-1].u))<eps) { last--; if (onleft(q[last],h[i].p)) q[last]=h[i]; } if (first<last) p[last-1]=line_intersect(q[last-1],q[last]); } while(first<last && !onleft(q[first],p[last-1])) last--; if (last-first<=1) return 0; p[last]=line_intersect(q[last],q[first]); return last-first+1; }//半平面交 bool seg_intersect(Point A, Point B, Point C, Point D) { double c1=cross(B-A,C-A),c2=cross(B-A,D-A); double c3=cross(D-C,A-C),c4=cross(D-C,B-C); return sign(c1)*sign(c2)<0&&sign(c3)*sign(c4)<0; }//線段判交 bool point_on_line(const Point &p,const Point &A,const Point &B) { return sign(cross(B-A, p-A))==0&&sign(dot(A-p,B-p))<=0; } bool in_polygon (const Point &p, const vector<Point> &poly) { int n=(int)poly.size(); int counter=0; for (int i=0;i<n;++i) { Point a=poly[i],b=poly[(i+1)%n]; if (point_on_line(p,a,b)) return true; // bounded included int x=sign(cross(p-a,b-a)); int y=sign(a.y-p.y); int z=sign(b.y-p.y); if (x>0&&y<=0&&z>0) counter++; if (x<0&&z<=0&&y>0) counter--; } return counter!=0; }//點在多邊形內 double area(const vector<Point> &poly) { double rt=0.0; int n=(int)poly.size(); for (int i=0;i<n;i++) rt+=cross(poly[i],poly[(i+1)%n]); return fabs(rt/2.0); }//多邊形的面積 vector<Point> convex(vector<Point> pts) { int n=(int)pts.size(); int m=0; vector<Point> cvx; sort(pts.begin(),pts.end()); for(int i=0;i<n;i++) { while(m>1&&onleft(cvx[m-2],cvx[m-1],pts[i])) {cvx.pop_back();m--;} cvx.push_back(pts[i]); m++; } int k=m; for (int i=n-2;i>=0;i--) { while(m > k && onleft(cvx[m - 2], cvx[m - 1], pts[i])) {cvx.pop_back();m--;} cvx.push_back(pts[i]); m++; } if(n>1) {m--;cvx.pop_back();} return cvx; }//凸包 int main() { return 0; }