首页 > 代码库 > 计算几何模板
计算几何模板
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define eps 1e-7using 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;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。