The question is to give an island with a convex polygon, and find the farthest distance from the sea. It can be converted into a convex polygon with a maximum of one circle.
The radius of the circle can be divided into two parts, but how can we determine the center of the circle. Determine whether the center exists. After moving the original convex polygon to the inside r (circle radius,
Calculate the semi-plane intersection for the new polygon. If the semi-plane intersection exists (it is a point), the circle of the current size can be placed.
You can use the basic N * N Complexity Algorithm in the previous article to calculate the semi-flat intersection. This article also involves the knowledge of how to push a straight line to the clockwise or clockwise direction.
The distance from the R to be moved. In fact, it can be calculated based on the idea of the unit circle. Because it is equivalent to taking a point in the original straight line as the center, using r as the radius of the circle, and with the original straight line into a 90 clip
Then, the coordinates of the points are (x0 + cos (PI/2 + θ), (y0 + sin (PI/2 + θ ))), the conversion is (x0-sin θ, y0 + cos θ ). You can directly
Find dx =/(vp [I]. y-vp [(I + 1) % nN]. y) * fR/fDis, dy = (vp [(I + 1) % nN]. x-vp [I]. x) * fR/fDis, indicating the length of a line segment.
The Code is as follows:
# Include <stdio. h>
# Include <string. h>
# Include <math. h>
# Include <algorithm>
# Include <vector>
Using namespace std;
Const double fPre = 1e-8;
Struct Point
{
Double x, y;
Point (){}
Point (const Point & p) {x = p. x, y = p. y ;}
Point (double fX, double fY): x (fX), y (fY ){}
Point & operator + (const Point & p)
{
X + = p. x;
Y + = p. y;
Return * this;
}
Point & operator + = (const Point & p)
{
Return * this = * this + p;
}
Point & operator-(const Point & p)
{
X-= p. x;
Y-= p. y;
Return * this;
}
Point & operator * (double fD)
{
X * = fD;
Y * = fD;
Return * this;
}
};
Typedef vector <Point> Polygon;
Int DblCmp (double fD)
{
Return fabs (fD) <fPre? 0: (fD> 0? 1:-1 );
}
Double Cross (Point a, Point B)
{
Return a. x * B. y-a. y * B. x;
}
Double Det (double fX1, double fY1, double fX2, double fY2)
{
Return fX1 * fY2-fX2 * fY1;
}
Double Cross (Point a, Point B, Point c)
{
Return Det (B. x-a. x, B. y-a. y, c. x-a. x, c. y-a. y );
}
Point Intersection (Point a1, Point a2, Point b1, Point b2)
{
Point a = a2-a1;
Point B = b2-b1;
Point s = b1-a1;
Return a1 + a * (Cross (B, s)/Cross (B, ));
}
Polygon Cut (Polygon & pg, Point a, Point B)
{
Polygon pgRet;
Int nN = pg. size ();
For (int I = 0; I <nN; ++ I)
{
Double fC = Cross (a, B, pg [I]);
Double fD = Cross (a, B, pg [(I + 1) % nN]);
If (DblCmp (fC)> = 0)
{
PgRet. push_back (pg [I]);
}
If (DblCmp (fC * fD) <0)
{
PgRet. push_back (Intersection (a, B, pg [I], pg [(I + 1) % nN]);
}
}
// Printf ("pgRet number: % d \ n", pgRet. size ());
Return pgRet;
}
Double Dis (Point a, Point B)
{
Return sqrt (. x-B. x) * (. x-B. x) + (. y-B. y) * (. y-B. y ));
}
// Returns the number of vertices in the half plane.
Int HalfPlane (Polygon & vp, double fR)
{
Polygon pg;
Pg. push_back (Point (-1e9,-1e9 ));
Pg. push_back (Point (1e9,-1e9 ));
Pg. push_back (Point (1e9, 1e9 ));
Pg. push_back (Point (-1e9, 1e9 ));
Int nN = vp. size ();
For (int I = 0; I <nN; ++ I)
{
Double fDis = Dis (vp [I], vp [(I + 1) % nN]);
Double dx = (vp [I]. y-vp [(I + 1) % nN]. y) * fR/fDis;
Double dy = (vp [(I + 1) % nN]. x-vp [I]. x) * fR/fDis;
Point a = vp [I], B = vp [(I + 1) % nN], c (dx, dy );
A + = c;
B + = c;
// Printf ("% f \ n", a. x, a. y, B. x, B. y );
Pg = Cut (pg, a, B );
If (pg. size () = 0)
{
Return 0;
}
}
Return pg. size ();
}
Int main ()
{
Int nN;
Vector <Point> vp;
While (scanf ("% d", & nN), nN)
{
Vp. clear ();
Point p;
For (int I = 0; I <nN; ++ I)
{
Scanf ("% lf", & p. x, & p. y );
Vp. push_back (p );
}
Double fMin = 0.0, fMax = 10000.0;
While (DblCmp (fMin-fMax ))
{
Double fMid = (fMin + fMax)/2;
Int nRet = HalfPlane (vp, fMid );
// Printf ("fMid: % f, nRet: % d \ n", fMid, nRet );
If (nRet = 0)
{
FMax = fMid;
} Www.2cto.com
Else
{
FMin = fMid;
}
}
Printf ("%. 6f \ n", fMax );
}
Return 0;
}