POJ-1584-A Round Peg in a Ground Hole-计算几何-凸多边形+多边形包含圆
来源:互联网 发布:java ssh 远程服务器 编辑:程序博客网 时间:2024/04/30 11:39
http://poj.org/problem?id=1584
题意:顺时针或逆时针的点,让你先判断多边形是否为凸多边形,如果不是输出HOLE IS ILL-FORMED
如果是,判断能不能把一个给定大小和位置的圆完全包含
if (ok)
printf("PEG WILL FIT\n");
else
printf("PEG WILL NOT FIT\n");
1先把点都变成逆时针,
然后判凸,
然后判圆心是否在多边形内,是的话再看是否被包含
#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <queue>#include <map>#include <set>#include <vector>#include <iostream>using namespace std; const double pi=acos(-1.0);double eps=1e-5; double tm[5][35];double max(double a,double b){return a>b?a:b;}double min(double a,double b){return a<b?a:b;}struct POINT { double x; double y; POINT(double a=0, double b=0) { x=a; y=b;} //constructor }; struct LINESEG { POINT s; POINT e; LINESEG(POINT a, POINT b) { s=a; e=b;} LINESEG() { } }; struct LINE // 直线的解析方程 a*x+b*y+c=0 为统一表示,约定 a >= 0 { double a; double b; double c; LINE(double d1=1, double d2=-1, double d3=0) {a=d1; b=d2; c=d3;} }; double multiply(POINT sp,POINT ep,POINT op) { return((sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y)); } double area_of_polygon(int vcount,POINT polygon[]) { int i; double s; if (vcount<3) return 0; s=polygon[0].y*(polygon[vcount-1].x-polygon[1].x); for (i=1;i<vcount;i++) s+=polygon[i].y*(polygon[(i-1)].x-polygon[(i+1)%vcount].x); return s/2; } // 如果输入顶点按逆时针排列,返回true bool isconterclock(int vcount,POINT polygon[]) { return area_of_polygon(vcount,polygon)>0; } void checkconvex(int vcount,POINT polygon[],bool bc[]) { int i,index=0; POINT tp=polygon[0]; for(i=1;i<vcount;i++) // 寻找第一个凸顶点 { if(polygon[i].y<tp.y||(fabs(polygon[i].y- tp.y)<eps&&polygon[i].x<tp.x)) { tp=polygon[i]; index=i; } } int count=vcount-1; bc[index]=1; while(count) // 判断凸凹性 { if(multiply(polygon[(index+1)%vcount],polygon[(index+2)%vcount],polygon[index%vcount])>=0 ) bc[(index+1)%vcount]=1; else bc[(index+1)%vcount]=0; index++; count--; } }bool isconvex(int vcount,POINT polygon[]) { bool bc[1005]; checkconvex(vcount,polygon,bc); for(int i=0;i<vcount;i++) // 逐一检查顶点,是否全部是凸顶点 if(!bc[i]) return false; return true; } /* 求点p到线段l的最短距离,并返回线段上距该点最近的点np 注意:np是线段l上到点p最近的点,不一定是垂足 */double dist(POINT p1,POINT p2) // 返回两点之间欧氏距离 { return( sqrt( (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y) ) ); } double dotmultiply(POINT p1,POINT p2,POINT p0) { return ((p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y)); } double relation(POINT p,LINESEG l) { LINESEG tl; tl.s=l.s; tl.e=p; return dotmultiply(tl.e,l.e,l.s)/(dist(l.s,l.e)*dist(l.s,l.e)); } // 求点C到线段AB所在直线的垂足 P POINT perpendicular(POINT p,LINESEG l) { double r=relation(p,l); POINT tp; tp.x=l.s.x+r*(l.e.x-l.s.x); tp.y=l.s.y+r*(l.e.y-l.s.y); return tp; } double ptolinesegdist(POINT p,LINESEG l,POINT &np) { double r=relation(p,l); if(r<0) { np=l.s; return dist(p,l.s); } if(r>1) { np=l.e; return dist(p,l.e); } np=perpendicular(p,l); return dist(p,np); } /* 计算点到折线集的最近距离,并返回最近点. 注意:调用的是ptolineseg()函数 */ double ptopointset(int vcount,POINT pointset[],POINT p,POINT &q) { int i; double cd=double(2147483647),td; LINESEG l; POINT tq,cq; for(i=0;i<vcount-1;i++) { l.s=pointset[i]; l.e=pointset[i+1]; td=ptolinesegdist(p,l,tq); if(td<cd) { cd=td; cq=tq; } } q=cq; return cd; } /* 判断圆是否在多边形内.ptolineseg()函数的应用2 */ bool CircleInsidePolygon(int vcount,POINT center,double radius,POINT polygon[]) { POINT q; double d; q.x=0; q.y=0; d=ptopointset(vcount,polygon,center,q); if(d<radius||fabs(d-radius)<eps) return false; else return true; } bool online(LINESEG l,POINT p) { return( fabs(multiply(l.e,p,l.s))<eps &&( ( (p.x-l.s.x)*(p.x-l.e.x)<=0 )&&( (p.y-l.s.y)*(p.y-l.e.y)<=0 ) ) ); } bool intersect(LINESEG u,LINESEG v) { return( (max(u.s.x,u.e.x)>=min(v.s.x,v.e.x))&& //排斥实验 (max(v.s.x,v.e.x)>=min(u.s.x,u.e.x))&& (max(u.s.y,u.e.y)>=min(v.s.y,v.e.y))&& (max(v.s.y,v.e.y)>=min(u.s.y,u.e.y))&& (multiply(v.s,u.e,u.s)*multiply(u.e,v.e,u.s)>=0)&& //跨立实验 (multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s)>=0)); } // (线段u和v相交)&&(交点不是双方的端点) 时返回true bool intersect_A(LINESEG u,LINESEG v) { return ((intersect(u,v))&& (!online(u,v.s))&& (!online(u,v.e))&& (!online(v,u.e))&& (!online(v,u.s))); } int insidepolygon(int vcount,POINT Polygon[],POINT q) { int c=0,i,n; LINESEG l1,l2; bool bintersect_a,bonline1,bonline2,bonline3; double r1,r2; l1.s=q; l1.e=q; l1.e.x=double(2147483647); n=vcount; for (i=0;i<vcount;i++) { l2.s=Polygon[i]; l2.e=Polygon[(i+1)%n]; if(online(l2,q)) return 1; // 如果点在边上,返回1 if ( (bintersect_a=intersect_A(l1,l2))|| // 相交且不在端点 ( (bonline1=online(l1,Polygon[(i+1)%n]))&& // 第二个端点在射线上 ( (!(bonline2=online(l1,Polygon[(i+2)%n])))&& /* 前一个端点和后一个端点在射线两侧 */ ((r1=multiply(Polygon[i],Polygon[(i+1)%n],l1.s)*multiply(Polygon[(i+1)%n],Polygon[(i+2)%n],l1.s))>0) || (bonline3=online(l1,Polygon[(i+2)%n]))&& /* 下一条边是水平线,前一个端点和后一个端点在射线两侧 */ ((r2=multiply(Polygon[i],Polygon[(i+2)%n],l1.s)*multiply(Polygon[(i+2)%n], Polygon[(i+3)%n],l1.s))>0) ) ) ) c++; } if(c%2 == 1) return 0; else return 2; } POINT p[1005];int main(){int i,j,k; int n;double r,x,y;while(cin>>n>>r>>x>>y){ if (n<3) break;double xx,yy;for (i=0;i<n;i++){scanf("%lf%lf",&xx,&yy);p[i].x=xx;p[i].y=yy;}if (isconterclock(n,p)==false)//先把点集变成逆时针{POINT TMP;for (i=0;i<n/2;i++){TMP=p[i];p[i]=p[n-i-1];p[n-i-1]=TMP;}}bool flag=isconvex(n,p);//判断是否多边形if (flag){POINT q(x,y);bool ok=CircleInsidePolygon(n,q,r,p);//判断圆是否被包含,这里的判断方法是圆心到各边的距离中的最小值是否大于等于半径if (insidepolygon(n,p,q)!=0)//所以需要先判断圆心是否被包含printf("PEG WILL NOT FIT\n");else{if (ok)printf("PEG WILL FIT\n");elseprintf("PEG WILL NOT FIT\n");}}elseprintf("HOLE IS ILL-FORMED\n");}return 0;}
0 0
- POJ-1584-A Round Peg in a Ground Hole-计算几何-凸多边形+多边形包含圆
- poj 1584 A Round Peg in a Ground Hole(判断凸多边形+圆是否在凸多边形内)
- poj 1584 A Round Peg in a Ground Hole 判断多边形是否为凸多边形 + 圆心是否在凸多边形内 + 圆是否在凸多边形内部
- poj 1584 A Round Peg in a Ground Hole(计算几何)
- poj 1584 A Round Peg in a Ground Hole(计算几何)
- poj 1584 A Round Peg in a Ground Hole 计算几何
- poj 1584 A Round Peg in a Ground Hole(计算几何)
- poj 1584A Round Peg in a Ground Hole(计算几何 判断凸包)
- POJ 1584 A Round Peg in a Ground Hole(凸多边形判断+点与多边形的位置关系)
- poj1584 A Round Peg in a Ground Hole 凸多边形判断 和多边形与圆的位置
- POJ 1584 A Round Peg in a Ground Hole(判断凸多边形,判断圆是否在凸多边形内)
- POJ 1584 A Round Peg in a Ground Hole 圆是否包含在凸包内
- POJ 1584 A Round Peg in a Ground Hole (判断凸多边形模板)
- POJ1584 A Round Peg in a Ground Hole 判断多边形是否为凸多边形,判断凸多边形是否在圆内
- POJ 1584 A Round Peg in a Ground Hole(凸包判定,多边形计算与判定)
- A Round Peg in a Ground Hole(POJ1584点在多边形内+是否为凸多边形)
- POJ 1584 A Round Peg in a Ground Hole
- poj 1584 A Round Peg in a Ground Hole
- 判断现有(输入的字符串是否相等)
- Stanford 机器学习 Week5 作业: Neural Networks: Learning
- 怎么查看编译的Linux内核源代码的版本信息
- [疯狂Java笔记]图形用户界面、AWT、Swing简介
- gulp压缩js和css
- POJ-1584-A Round Peg in a Ground Hole-计算几何-凸多边形+多边形包含圆
- JSP_004_Cookie介绍02—Cookie的最大生命和Cookie的path
- js中小数向上取整数,向下取整数,四舍五入取整数的实现。
- 机器学习中的训练集,验证集及测试集的关系
- 关于jQuery $(selector).addClass(class) IE8 兼容的说法
- Spark性能优化(1)
- Android4.2.2自增物理按键
- NEXTVAL 和 CURRVAL 运算符和oracle的sequence设置说明
- linux下如何修改DNS地址