计算几何模板四(多边形)
来源:互联网 发布:小说封面设计软件 编辑:程序博客网 时间:2024/05/20 22:02
计算几何模板四(多边形)
#include<iostream>#include<cstdio>#include<cmath>#include<memory.h>#include<cstring>#include<algorithm>using namespace std;#define Sgn(x) (((x)<0)?(-1):(1))#define eps 1e-8#define INF 1e10#define Pi (acos(-1.0))double Deg2Rad(double deg) {return (deg*Pi/180.0);}double Rad2Deg(double rad) {return (rad*180.0/Pi);}double Sin(double deg) {return sin(Deg2Rad(deg));}double Cos(double deg) {return cos(Deg2Rad(deg));}double ArcSin(double val) {return Rad2Deg(asin(val));}double ArcCos(double val) {return Rad2Deg(acos(val));}//点struct POINT{ double x,y; POINT():x(0),y(0){} POINT(double _x,double _y):x(_x),y(_y){};};//两个点的距离double Distance(const POINT &a,const POINT &b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}//线段struct SEG{ POINT a;//起点 POINT b;//终点 SEG(){}; SEG(POINT _a,POINT _b):a(_a),b(_b){};};//有公共端点o叉乘,并判拐,若正p0->p1->p2拐向左double Cross(const POINT &a,const POINT &b,const POINT &o){ return (a.x-o.x)*(b.y-o.y)-(b.x-o.x)*(a.y-o.y);}//判等(值,点)bool IsEqual(double a,double b){ return (abs(a-b)<eps);}bool IsEqual(const POINT &a,const POINT &b){ return (IsEqual(a.x,b.x)&&IsEqual(a.y,b.y));}//判断点是否在线段上bool IsOnSeg(const SEG &seg,const POINT &p){ return (IsEqual(p,seg.a)||IsEqual(p,seg.b))|| (((p.x-seg.a.x)*(p.x-seg.b.x)<0|| (p.y-seg.a.y)*(p.y-seg.b.y)<0)&& (IsEqual(Cross(seg.b,p,seg.a),0)));}//判断两条线段是否相交,端点重合算相交bool IsIntersect(const SEG &u,const SEG &v){ return (Cross(v.a,u.b,u.a)*Cross(u.b,v.b,u.a)>=0)&& (Cross(u.a,v.b,v.a)*Cross(v.b,u.b,v.a)>=0)&& (max(u.a.x,u.b.x)>=min(v.a.x,v.b.x))&& (max(v.a.x,v.b.x)>=min(u.a.x,u.b.x))&& (max(u.a.y,u.b.y)>=min(v.a.y,v.b.y))&& (max(v.a.y,v.b.y)>=min(u.a.y,u.b.y));}//多边形,逆时针或顺时针给出x,ystruct POLY{ int n; double *x;//n个点 double *y;//x,y为点的指针,首尾必须重合 POLY():n(0),x(NULL),y(NULL){}; POLY(int _n,const double *_x,const double *_y) { n=_n; x=new double[n+1]; memcpy(x,_x,n*sizeof(double)); x[n]=_x[0]; y=new double[n+1]; memcpy(y,_y,n*sizeof(double)); y[n]=_y[0]; }};//多边形顶点POINT Vertex(const POLY &poly,int idx){ idx%=poly.n; return POINT(poly.x[idx],poly.y[idx]);}//多边形的边SEG Edge(const POLY &poly,int idx){ idx%=poly.n; return SEG(POINT(poly.x[idx],poly.y[idx]), POINT(poly.x[idx+1],poly.y[idx+1]));}//多边形的周长double Perimeter(const POLY &poly){ double p=0.0; for(int i=0;i<poly.n;i++) p=p+Distance(Vertex(poly,i),Vertex(poly,i+1)); return p;}double Area(const POLY &poly){ if(poly.n<3) return double(0); double s=poly.y[0]*(poly.x[poly.n-1]-poly.x[1]); for(int i=1;i<poly.n;i++) s+=poly.y[i]*(poly.x[i-1]-poly.x[(i+1)%poly.n]); return s/2;}//多边形的重心POINT InCenter(const POLY &poly){ double S,Si,Ax,Ay; POINT p; Si=(poly.x[poly.n-1]*poly.y[0]-poly.x[0]*poly.y[poly.n-1]); S=Si; Ax=Si*(poly.x[0]+poly.x[poly.n-1]); Ay=Si*(poly.y[0]+poly.y[poly.n-1]); for(int i=1;i<poly.n;i++) { Si=(poly.x[i-1]*poly.y[i]-poly.x[i]*poly.y[i-1]); Ax+=Si*(poly.x[i-1]+poly.x[i]); Ay+=Si*(poly.y[i-1]+poly.y[i]);; S+=Si; } S=S*3; return POINT (Ax/S,Ay/S);}//判断点是否在多边形上bool IsOnPoly(const POLY &poly,const POINT &p){ for(int i=0;i<poly.n;i++) { if(IsOnSeg(Edge(poly,i),p)) { return true; } } return false;}//判断点是否在多边形内部bool IsInPoly(const POLY &poly,const POINT &p){ SEG L(p,POINT(INF,p.y)); int count=0; for(int i=0;i<poly.n;i++) { SEG S=Edge(poly,i); if(IsOnSeg(S,p)) return true;//如果在poly上则返回true if(!IsEqual(S.a.y,S.b.y)) { POINT &p=(S.a.y>S.b.y)?(S.a):(S.b); if(IsOnSeg(L,p)) { ++count; } else if(!IsOnSeg(L,S.a)&&!IsOnSeg(L,S.b)&&IsIntersect(S,L)) { ++count; } } } return (count%2!=0);}//判断是否为简单多边形bool IsSimple(const POLY &poly){ if(poly.n<3) return false; SEG L1,L2; for(int i=0;i<poly.n-1;i++) { L1=Edge(poly,i); for(int j=i+1;j<poly.n;j++) { L2=Edge(poly,j); if(j==i+1) { if(IsOnSeg(L1,L2.b)||IsOnSeg(L2,L1.a)) return false; } else if(j==poly.n-i-1) { if(IsOnSeg(L1,L2.a)||IsOnSeg(L2,L1.b)) return false; } else { if(IsIntersect(L1,L2)) return false; } } } return false;}//点阵的凸包,返回一个多边形POLY ConvexHull(const POINT *set,int n)//不适用于点少于3个的情况{ POINT * points=new POINT[n]; memcpy(points,set,n*sizeof(POINT)); double *X=new double[n]; double *Y=new double[n]; int k=0,top=2; for(int i=1;i<n;i++) { if((points[i].y<points[k].y)|| ((points[i].y==points[k].y)&& (points[i].x<points[k].x))) { k=i; } } swap(points[0],points[k]); for(int i=1;i<n-1;i++) { k=i; for(int j=i+1;j<n;j++) { if((Cross(points[j],points[k],points[0])>0)|| ((Cross(points[j],points[k],points[0])==0)&& (Distance(points[0],points[j])<Distance(points[0],points[k])))) { k=j; } } swap(points[i],points[k]); } X[0]=points[0].x;Y[0]=points[0].y; X[1]=points[1].x;Y[1]=points[1].y; X[2]=points[2].x;Y[2]=points[2].y; for(int i=3;i<n;i++) { while(Cross(points[i],POINT(X[top],Y[top]), POINT(X[top-1],Y[top-1]))>=0) { top--; } top++; X[top]=points[i].x; Y[top]=points[i].y; } delete[] points; POLY poly(++top,X,Y); delete[] X; delete[] Y; return poly;}
1 0
- 计算几何模板四(多边形)
- 计算几何-计算多边形面积(模板)
- 计算几何:多边形重心模板
- 几何(多边形模板)
- 二维计算几何模板--多边形/凸包
- <模板><计算几何>点与多边形的位置关系
- 求多边形重心(计算几何)
- 求多边形面积(计算几何)
- nyoj_3:多边形重心问题(计算几何)
- 判断多边形凹凸(计算几何基础)
- 判断多边形凹凸(计算几何)
- 计算几何_多边形
- 【计算几何】多边形
- 计算几何之多边形
- 用数学方法解决工程问题系列(四) 计算包围一组多边形的几何形状
- [计算几何] 计算多边形面积
- 计算几何 - 二维几何基础 (模板)
- poj3304Segments+计算几何(二维几何模板)
- 图解Linux命令之--ls命令
- excel删除制指字符所在的行
- mongodb 高级部分 group by case when select distinct substr(sdf,0,6)
- Windows下Nginx的启动、停止等命令
- 解决DEDE防止图片撑破页面,文章内容中的图片自适应宽度
- 计算几何模板四(多边形)
- jsp小知识
- 506. Relative Ranks
- android 获取SHA1值,查看SHA1值,查看MD5值
- IIS做反向代理,详细步骤和解析!
- 数据结构和算法
- iOS 设置UILabel内容行间距
- 工作流分析——杂谈
- 分离MindMapper主题的方法