Test instructions: The coordinates of n points of a convex n-edged shape are given in a clockwise or counterclockwise order, and then the area at which the center of the Circle crosses the (0,0) circle and convex n is greater than or equal to r, asking the minimum radius of the circle.
The problem is simply a pit dad, a variety of details wrong. Revision change a day, and finally see other people's puzzle also still do not understand why onsegment function to write like that ... Clearly cannot determine whether the point is ╮(╯▽╰)╭ on the line segment
Drawing ideas are not difficult to think of, the convex n edge of each edge and circle to determine the relationship, if the edge of the two points are in the circle, two edges corresponding to a triangular area, if a point in the circle outside a circle (including the boundary), that is a triangle plus a fan, if two points are in the round, divided into two cases, And the circle has two intersection words is two fan and a triangle, if and circle no intersection is a fan.
#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <cmath>using namespace STD;Const DoubleEPS =1e-9;Const DoublePI =ACOs(-1);intDCMP (Doublex) {if(fabs(x) < EPS)return 0;returnX >0?1: -1;}structPoint {Doublex, y; Point (DoubleA =0,Doubleb =0): X (a), Y (b) {}};typedefPoint Vector; Vectoroperator+ (Constvector& A,Constvector& b) {returnVector (a.x + b.x, A.Y + b.y); }vectoroperator- (Constvector& A,Constvector& b) {returnVector (a.x-b.x, A.Y-B.Y); }vectoroperator* (Constvector& A,Double& B) {returnVector (a.x * b, a.y * b); }vectoroperator/ (Constvector& A,Double& B) {returnVector (a.x/b, a.y/b); }BOOL operator== (Constvector& A,Constvector& b) {return!DCMP (a.x-b.x) &&!dcmp (A.Y-B.Y); }BOOL operator< (Constvector& A,Constvector& b) {returna.x < b.x | | (a.x = = b.x && a.y < B.Y); }DoubleDot (Constvector& A,Constvector& b) {returna.x * b.x + a.y * B.Y; }DoubleLength (Constvector& a) {return sqrt(Dot (A, a)); }DoubleCross (Constvector& A,Constvector& b) {returna.x * B.Y-A.Y * b.x; }DoubleAngle (Constvector& A,Constvector& b) {return ACOs(Dot (A, b)/Length (a)/length (b)); }structline {point P; Vector v;DoubleAng Line () {} line (point A, Vector b): P (a), V (b) {ang =atan2(B.y, b.x); }BOOL operator< (Constline& L)Const{returnAng < L.ang; } Point Point (DoubleA) {returnP + v * A; }};structCircle {DoubleR Point C; Circle () {} circle (point A,Doubleb): C (a), R (b) {} Point point (DoubleA) {returnPoint (c.x +Cos(a) * R, C.y +Sin(a) * R); }};BOOLIspointincircle (Point P, Circle C) {returnDCMP (Length (c.c-p)-C.R) <=0;}BOOLOnsegment (point P, point P1, point p2) {returnDCMP (Dot (P1-p, p2-p)) <=0;//It's confusing here .}voidSegmentcircleintersection (Point P1, point P2, Circle C, point* Sol,int& num) {DoubleT1, T2;DoubleA = (P1-C.C). x, B = (P2-P1). x, C = (p1-c.c). Y, D = (p2-p1). Y;DoubleE = b * B + d * d, F =2* (A * b + c * d), G = A * a + c * C-C.R * C.R;DoubleDelta = f * F-4* E * g; Point P; num =0;if(Delta < DCMP)0)return;Else if(dcmp (delta) = =0) {T1 = t2 = (-f)/(2* e); p = p1 + (p2-p1) * T1;if(Onsegment (P, p1, p2)) sol[num++] = p; }Else{T1 = (-F-sqrt(Delta)) / (2* e); p = p1 + (p2-p1) * T1;if(Onsegment (P, p1, p2)) sol[num++] = p; T2 = (-f +sqrt(Delta)) / (2* e); p = p1 + (p2-p1) * T2;if(Onsegment (P, p1, p2)) sol[num++] = p; }}DoubleFanarea (Circle C, vector v1, vector v2) {Doublerad = Angle (v1, v2);if(dcmp (RAD-PI) = =0) rad =0;returnC.R * C.R * rad *0.5;}DoubleGetcommonarea (Point P1, point P2, point P3, Circle C) {intFlag1 = Ispointincircle (P2, C);intFlag2 = ispointincircle (p3, C);intNum Point sol[5];if(Flag1 + Flag2 = =2)return fabs(Cross (P2-P1, P3-P1)) *0.5;if(Flag1 + Flag2 = =1) {segmentcircleintersection (P2, p3, C, Sol, num);if(FLAG1)returnFanarea (C, P3-P1, sol[0]-P1) +fabs(Cross (P2-P1, sol[0]-p1)) *0.5;returnFanarea (C, P2-P1, sol[0]-P1) +fabs(Cross (P3-P1, sol[0]-p1)) *0.5; } segmentcircleintersection (P2, p3, C, Sol, num);//Note that two endpoints correspond to different intersections, and the write is wrong. if(num = =2)returnFanarea (C, P2-P1, sol[0]-P1) +fabs(Cross (sol[0]-P1, sol[1]-p1)) *0.5+ Fanarea (C, P3-P1, sol[1]-P1);returnFanarea (C, P2-P1, P3-P1);}Const intN = -; Point P[n];DoubleRintNDoubleCommonarea (Circle C) {Doubleres =0; for(inti =0; I < n; i++) Res + = Getcommonarea (C.C, p[i], P[i +1], C);returnRes;}intMain () {intCAS =1; while(scanf("%d", &n) = =1&& N) {scanf("%LF", &r); for(inti =0; I < n; i++)scanf("%LF%LF", &p[i].x, &P[I].Y); P[n] = p[0];DoubleL =0, r =1e9; while(DCMP (R-L) >0) {DoubleMid = (L + R) *0.5;if(DCMP (Commonarea (The Circle (point) (0,0), mid)-R) >=0) R = Mid;ElseL = Mid; }printf("Case%d:%.2lf\n", cas++, L); }return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
UVA 11177 (Polygon and Circle intersection)