Poj-1584-a Round Peg in A Ground hole-compute geometry-convex polygon + polygon containing circle

Source: Internet
Author: User
Tags min

http://poj.org/problem?id=1584

Test instructions: Clockwise or counter-clockwise point, let you first determine whether the polygon is convex, if not output hole is ill-formed

If yes, determine if a circle of a given size and position can be completely contained

if (OK)
printf ("PEG would fit\n");
Else
printf ("PEG would not fit\n");



1 Turn the dots counterclockwise,

And then the convex,

Then judge whether the center is inside the polygon, and then see if it is included


#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm&
Gt #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 {do 
 Uble 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//linear analytic equation a*x+b*y+c=0 for a uniform representation, convention 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; DoubleS 
 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; }//If the input vertices are in a counter-clockwise order, return 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++)//Find first convex vertex {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)//judgment convexity {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++)//check vertices individually, whether fullThe part is the convex vertex if (!bc[i]) return false; 
return true; }/* Find the shortest distance from p to line L and return the point closest to the point on the segment NP Note: NP is the nearest point on the line of the segment L, not necessarily perpendicular */double dist (point p1,point p2)//Return two points Euclidean distance 
From {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)); 
 }//To point C to the line where AB is located perpendicular P point perpendicular (points 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); 
}/* Calculates the closest distance from a point to a polyline set and returns the nearest point. Note: the Ptolineseg () function is called */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&LT;CD) {cd=td; 
  CQ=TQ; 
 }} Q=cq; 
return CD;  
 }/* Determines whether the circle is within the polygon. Application of Ptolineseg () function 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)) && Repulsion Experiment (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) &&//cross-stand Experiment (multiply (U.S,V.E,V.S) *multiply (V.E,U.E,V.S) >=0)); }//(segment U and v intersect) && return 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;  If the dot is on the side, return 1 if ((Bintersect_a=intersect_a (L1,L2)) | | |//INTERSECT and not at the end point ((Bonline1=online (l1,polygon[(i+1)%n)) && The second endpoint is on a ray ((!) ( 
  Bonline2=online (l1,polygon[(i+2)%n])) &&/* Previous endpoint and last endpoint on both sides of Ray */((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]) &&/* The next edge is a horizontal line, the previous endpoint and the latter endpoint are on both sides of the ray */((r2=multiply 
 [(i+2)%n],l1.s) *multiply (polygon[(i+2)%n], polygon[(i+3)%n],l1.s)))) 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)//First turn the point set to counter-clockwise {dot 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);
			Determines if the polygon if (flag) {point q (x, y);		BOOL Ok=circleinsidepolygon (N,Q,R,P); Judging whether a circle is included, the method here is to determine whether the minimum value in the distance from the center to each edge is greater than or equal to the radius if (Insidepolygon (n,p,q)!=0)//So you need to first determine if the center is contained
				printf ("PEG would not fit\n");
			else {if (OK) printf ("PEG would fit\n");
			else printf ("PEG would not fit\n");


	}} else printf ("HOLE is ill-formed\n");
	
} return 0; }


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.