计算几何模板
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #define eps 1e-7 using namespace std; struct Point{ double x,y; Point(){} Point(double x,double y):x(x),y(y){} void input() { scanf("%lf %lf",&x,&y); } }; typedef Point Vector;//从程序上,Vector只是Point的别名 int dcmp(double x)//控制精度 { if(fabs(x)<eps) return 0; else return x<0?-1:1; } double toRad(double deg)//角度变为弧度 { return deg/180.0*acos(-1.0); } Vector operator+(Vector A,Vector B)//向量加 { return Vector(A.x+B.x, A.y+B.y); } Vector operator-(Vector A,Vector B)//向量减 { return Vector(A.x-B.x,A.y-B.y); } Vector operator*(Vector A,double p)//向量数乘 { return Vector(A.x*p,A.y*p); } Vector operator/(Vector A,double p)//向量数除 { return Vector(A.x/p,A.y/p); } bool operator<(const Point &A,const Point &B)//两点比较 { return dcmp(A.x-B.x)<0 || (dcmp(A.x-B.x) == 0 && dcmp(A.y-B.y) < 0); } bool operator==(const Point &A, const Point &B)//两点相等 { return dcmp(A.x-B.x) == 0 && dcmp(A.y-B.y) == 0; } struct Line { Point s,e; Vector v; Line(){} Line(Point s, Point v, int type)://法向量式 s(s),v(v){} Line(Point s, Point e):s(s),e(e)//两点式 { v=e-s; } }; double Dot(Vector A,Vector B)//向量点乘,|A|*|B|*cos<A,B> { return A.x*B.x+A.y*B.y; } double Length(Vector A)//向量模 { return sqrt(Dot(A,A)); } double Angle(Vector A,Vector B)//向量夹角 { return acos(Dot(A,B)/Length(A)/Length(B)); } double Cross(Vector A,Vector B)//向量叉积 { return A.x*B.y-B.x*A.y; } double Area2(Point A,Point B,Point C)//向量的有向面积,三角形面积的2倍 { return Cross(B-A,C-A); } double Dist(Point A,Point B)//两点之间的距离 { return Length(A-B); } Vector Rotate(Vector A, double rad)//向量逆时针旋转 { return Vector(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad)); } Vector Normal(Vector A)//向量单位法向量,前提不是零向量,即左转90度 { double L=Length(A); return Vector(-A.y/L,A.x/L); } Point GetLineIntersection(Line l1,Line l2)//两直线的交点,调用前确保两条直线有唯一交点 { Point P=l1.s; Vector v=l1.v; Point Q=l2.s; Vector w=l2.v; Vector u=P-Q; double t=Cross(w,u)/Cross(v,w);//注意分母不能为0 return P+v*t; } double DistanceToLine(Point P,Line L)//点到直线的距离 { Point A,B; A=L.s,B=L.e; Vector v1=B-A,v2=P-A; return fabs(Cross(v1,v2)/Length(v1)); } double DistanceToSegment(Point P,Line L)//点到线段的距离 { Point A,B; A=L.s,B=L.e; if(A==B) return Length(P-A); Vector v1=B-A,v2=P-A,v3=P-B; if(dcmp(Dot(v1,v2))<0) return Length(v2); else if(dcmp(Dot(v1,v3)>0)) return Length(v3); else return fabs(Cross(v1,v2))/Length(v1); } Point GetLineProjection(Point P,Line L)//点在直线上的投影 { Point A,B; A=L.s,B=L.e; Vector v=B-A; return A+v*(Dot(v,P-A)/Dot(v,v)); } bool OnSegment(Point p,Line l)//点在线段上包括端点 { Point a1=l.s; Point a2=l.e; return dcmp(Cross(a1-p,a2-p))==0 && dcmp(Dist(p,a1)+Dist(p,a2)-Dist(a1,a2))==0; } bool Paralled(Line l1,Line l2)//直线平行 { return dcmp(Cross(l1.e-l1.s,l2.e-l2.s))==0; } bool SegmentProperIntersection(Line l1,Line l2)//线段是否相交 { if(Paralled(l1,l2)) return false; Point t=GetLineIntersection(l1,l2); if(OnSegment(t,l1)) return true; return false; } double PolygonArea(Point *p, int n)//求多边形面积 { double area = 0; for(int i=1; i<n-1; i++) area += Cross(p[i]-p[0],p[i+1]-p[0]); return area/2.0; } int ConvexHull(Point *p,int n,Point *ch) //求凸包 { sort(p,p+n); int m=0; for ( int i = 0; i < n; ++i ) { while ( m > 1 && Cross( ch[m - 1] - ch[m - 2], p[i] - ch[m - 2] ) <= 0 ) --m; ch[m++] = p[i]; } int k = m; for ( int i = n - 2; i >= 0; --i ) { while ( m > k && Cross( ch[m - 1] - ch[m - 2], p[i] - ch[m - 2] ) <= 0 ) --m; ch[m++] = p[i]; } if ( n > 1 ) --m; return m; } int main() { return 0; }
posted on 2014-08-17 16:04 后端bug开发工程师 阅读(334) 评论(0) 编辑 收藏 举报