Topic Link: UVA 12307-smallest enclosing Rectangle
The two pairs of heel-to-point circumference are rectangular, and the minimum values of all feasible rectangles are enumerated.
#include <cstdio> #include <cstring> #include <cmath> #include <vector> #include <complex > #include <algorithm>using namespace std;typedef pair<int,int> pii;const Double pi = 4 * atan (1); Const Doub Le EPS = 1e-10;inline int dcmp (double x) {if (Fabs (x) < EPS) return 0; else return x < 0? -1:1;} Inline double getdistance (double x, double y) {return sqrt (x * x + y * y);} Inline double Torad (double deg) {return deg/180 * PI;} struct point {double x, y; Point (Double x = 0, double y = 0): x (x), Y (y) {}void read () {scanf ("%lf%lf", &x, &y);} void Write () {printf ("%lf%lf", x, y);} BOOL operator = = (CONST point& u) Const {return dcmp (x-u.x) = = 0 && dcmp (y-u.y) = = 0;} BOOL operator! = (const point& u) Const {return! ( *this = = u); }bool operator < (const point& u) Const {return x < u.x | | (x = = u.x && y < u.y); }bool operator > (const point& u) Const {return u < *this;} BOOL OperAtor <= (const point& u) Const {return *this < u | | *this = u;} BOOL operator >= (const point& u) const {return *this > U | | *this = u;} Point operator + (const point& u) {return point (x + u.x, y + u.y);} Point operator-(const point& u) {return point (x-u.x, y-u.y);} Point operator * (const double u) {return point (x * u, y * u);} Point operator/(const double u) {return point (x/u, y/u);} Double operator * (const point& u) {return x*u.y-y*u.x;}}; typedef point VECTOR;TYPEDEF vector<point> polygon;struct line {Double A, B, C; Line (Double A = 0, double b = 0, double c = 0): A (a), B (b), C (c) {}};struct dirline {point P; Vector v;double Ang;dirline () {}dirline (point P, Vector v): P (P), V (v) {ang = atan2 (V.y, v.x);} BOOL operator < (const dirline& u) const {return Ang < U.ang;}}; struct Circle {point o;double R; Circle () {}circle (Point O, double r = 0): O (O), R (r) {}void read () {o.read (), scanf ("%lf", &r);} PointPoint (Double rad) {return point (o.x + cos (rad) *r, O.y + sin (rad) *r);} Double Getarea (double rad) {return rad * R * R/2;}}; Namespace punctual {Double getdistance (point A, point B) {double x=a.x-b.x, y=a.y-b.y; return sqrt (x*x + y*y);}}; namespace Vectorial {/* dot product: The product of two vector lengths multiplied by the cosine of their angle, the angle is greater than 90 degrees the product is negative */double Getdot (vector A, vector b) {return a.x * b.x + A.Y * B.Y; }/* Cross product: The cross product is equal to two vectors consisting of a triangle with a direction area of twice times, crosses (V, w) =-cross (W, v) */double Getcross (vector A, vector b) {return a.x * B.Y-A.Y * b.x; }double GetLength (Vector a) {return sqrt (Getdot (A, a));} Double Getplength (Vector a) {return Getdot (A, a);} Double Getangle (Vector u) {return atan2 (u.y, u.x);} Double Getangle (vector A, vector b) {return ACOs (Getdot (A, B)/GetLength (a)/GetLength (b));} Vector Rotate (vector A, double rad) {return vector (A.x*cos (RAD)-a.y*sin (RAD), A.x*sin (RAD) +a.y*cos (RAD));} /* unit normal */vector Getnormal (Vector a) {double L = getlength (a); return Vector (-a.y/l, a.x/l);}}; Namespace Complexvector {TypEdef complex<double> point;typedef point vector;double getdot (vector A, vector b) {return real (Conj (a) *b);} Double Getcross (vector A, vector b) {return imag (Conj (a) *b); Vector Rotate (vector A, double rad) {return a*exp (point (0, RAD));}}; Namespace Linear {using namespace vectorial; Line GetLine (double x1, double y1, double x2, double y2) {return line (y2-y1, x1-x2, y1*x2-x1*y2);} Line GetLine (double A, double b, point u) {return line (A, B, u.y * b-u.x * a);} BOOL Getintersection (line p, line Q, point& o) {if (Fabs (P.A * q.b-q.a * p.b) < EPS) return false;o.x = (Q.C * p. B-P.C * q.b)/(P.A * q.b-q.a * p.b); o.y = (Q.C * p.a-p.c * q.a)/(P.B * q.a-q.b * p.a); return true;} /* Intersection of linear PV and line QW */bool getintersection (point P, Vector v, point Q, Vector W, point& o) {if (dcmp (Getcross (V, w)) = = 0 ) return false; Vector u = p-q;double k = Getcross (w, u)/Getcross (V, w); o = p + v * K;return true;} /* point P to line ab distance */double getdistancetolineb) {return fabs (Getcross (b-a, p-a)/GetLength (B-A));} Double getdistancetosegment (point P, point A, point B) {if (a = = b) return getlength (P-A); Vector v1 = b-a, v2 = p-a, V3 = p-b;if (dcmp (Getdot, V1) < 0) return v2 (getlength); else if (V2 (dcmp (Getdot, V 3)) > 0) return GetLength (V3), Else return fabs (Getcross (v1, v2)/GetLength (v1));} /* point P on the line ab projection */point getpointtoline (points P, a, point B) {Vector v = b-a; return a+v* (Getdot (V, p-a)/Getdot (V, v)); }/* to determine if a segment has an intersection */bool haveintersection (Point A1, Point A2, point B1, point B2) {double C1=getcross (a2-a1, b1-a1), c2=getc Ross (A2-A1, B2-A1), C3=getcross (B2-B1, A1-B1), C4=getcross (B2-B1,A2-B1), return dcmp (C1) *dcmp (C2) < 0 && dcmp (C3) *dcmp (C4) < 0;} /* Determine if the point is */bool onsegment on a line segment {return dcmp (Getcross (A-p, b-p)) = = 0 && dcmp (Getdot (A- P, b-p)) < 0; }bool Onleft (dirline L, point P) {return dcmp (L.V * (P-L.P)) > 0;}} Namespace triangular {using namespace VectoriAl;double Getangle (Double A, double b, double c) {return ACOs ((a*a+b*b-c*c)/(2*a*b));} Double Getarea (double A, double b, double c) {double s = (a+b+c)/2; return sqrt (s* (s-a) * (s-b) * (S-C));} Double Getarea (Double A, double h) {return a * H/2;} Double Getarea (Point A, point B, point C) {return fabs (Getcross (b-a, c-a))/2;} Double Getdirarea (Point A, point B, point C) {return Getcross (b-a, c-a)/2;}}; Namespace polygonal {using namespace vectorial;using namespace linear;double getarea (point* p, int n) {double ret = 0;for (int i = 0; i < n-1; i++) ret + = (p[i]-p[0]) * (p[i+1]-p[0]); return RET/2;} /* Convex package */int getconvexhull (point* p, int n, point* ch) {sort (p, p + N); int m = 0;for (int i = 0; i < n; i++) {/* collinear */ while (M > 1 && dcmp (Getcross (ch[m-1]-ch[m-2), p[i]-ch[m-1]) < 0) M--;while (M > 1 && dcmp (get Cross (Ch[m-1]-ch[m-2], p[i]-ch[m-1])) <= 0) m--;ch[m++] = P[i];} int k = m;for (int i = n-2; I >= 0; i--) {/* collinear *///while (M > K && dcmp (Getcross (Ch[m-1]-ch[m-2], p[i]-ch[m-2]) < 0) M--;while (M > K && dcmp (Getcross (ch[m -1]-ch[m-2], p[i]-ch[m-2])) <= 0) m--;ch[m++] = P[i];} if (n > 1) m--;return m;} int Ispointinpolygon (Point O, point* p, int n) {int wn = 0;for (int i = 0; i < n; i++) {int J = (i + 1)% n;if (onsegm ENT (o, p[i], p[j])) return 0; the boundary int k = dcmp (Getcross (P[j]-p[i], o-p[i])); int D1 = DCMP (p[i].y-o.y); int d2 = DCMP (P[J].Y-O.Y); if (k > 0 &am p;& D1 <= 0 && d2 > 0) wn++;if (k < 0 && D2 <= 0 && d1 > 0) wn--;} Return WN? -1:1;} /* Rotate Jam */void rotatingcalipers (point *p, int n, vector<pii>& sol) {sol.clear (); int j = 1; P[n] = p[0];for (int i = 0; I < n; i++) {while (Getcross (p[j+1]-p[i+1], p[i]-p[i+1]) > Getcross (p[j]-p[i+1], p[i]-p[i+1])) j = (j+1)% N;sol.push_back ( Make_pair (i, J)); Sol.push_back (Make_pair (i + 1, j + 1));}} void Rotatingcalipersgetrectangle (Point *p, Int. N, double& area, DOUBLe& perimeter) {P[n] = p[0];int L = 1, R = 1, j = 1;area = perimeter = 1e20;for (int i = 0; i < n; i++) {Vector v = (P[i+1]-p[i])/GetLength (P[i+1]-p[i]), while (DCMP (Getdot (V, p[r%n]-p[i))-Getdot (V, p[(r+1)%n]-p[i])) < 0) r++; while (J < R | | dcmp (Getcross (V, p[j%n]-p[i])-Getcross (v,p[(j+1)%n]-p[i])) < 0) J++;while (L < J | | dcmp (GETDOT (V, P[l%n]-p[i])-Getdot (V, p[(l+1)%n]-p[i])) > 0) l++;d ouble w = Getdot (V, P[r%n]-p[i])-getdot (V, p[l%n]-p[i]);d ouble h = getdistancetoline (p[j%n], p[i], p[i+1]), area = min (area, W * h);p erimeter = min (Perimeter, 2 * w + 2 * h);}} /* Calculate the half plane intersection can be used increment method, O (n^2), initially set 4 infinity half plane *//* with a straight line a->b cut polygon U, return to the left. May degenerate into a single point or segment */polygon Cutpolygon (Polygon u, point A, point B) {Polygon Ret;int n = u.size (); for (int i = 0; i < n; i++) {Point c = u[i], d = u[(i+1)%n];if (dcmp ((b-a) * (c-a)) >= 0) Ret.push_back (c); if (dcmp ((b-a) * (c-d))! = 0) {Point T;geti Ntersection (A, b-a, C, d-c, T); if (Onsegment (t, C, D)) Ret.push_back (t);}} return ret;} /* Half plane intersect */int halfplaneintersection (dirline* li, int n, point* poly) {sort (Li, Li + N); int first, last; point* p = new Point[n];D irline* q = new Dirline[n];q[first=last=0] = li[0];for (int i = 1; i < n; i++) {while (First & Lt Last &&!onleft (Li[i], p[last-1]) Last--;while (First < last &&!onleft (Li[i], P[first])) first++;q[+ +last] = li[i];if (dcmp (Q[LAST].V * q[last-1].v) = = 0) {last--;if (Onleft], q[last)) LI[I].P] = Q[last];} if (first < last) getintersection (Q[LAST-1].P, Q[LAST-1].V, Q[LAST].P, Q[LAST].V, p[last-1]);} while (first < last &&!onleft (Q[first], p[last-1)) last--;if (Last-first <= 1) {delete [] p; Delete [] Q return 0; }getintersection (Q[LAST].P, Q[LAST].V, Q[FIRST].P, Q[FIRST].V, p[last]); int m = 0;for (int i = first; I <= last; i++) p oly[m++] = p[i];d elete [] p; Delete [] Q;return m;}; Namespace Circular {using namespace Linear;using namespace vectorial;using namespace triangular;/* straight and original intersection */int Getlinec Ircleintersection (POint p, point Q, Circle O, double& t1, double& T2, vector<point>& sol) {vector v = q-p;/* need to empty sol before use */ Sol.clear ();d ouble a = v.x, B = p.x-o.o.x, c = v.y, d = p.y-o.o.y;double e = a*a+c*c, F = (a*b+c*d), G = B*b+d*d-o . r*o.r;double Delta = f*f-4*e*g;if (dcmp (Delta) < 0) return 0;if (dcmp (delta) = = 0) {T1 = t2 =-F/(2 * e); sol.push_ Back (p + v * t1); return 1;} T1 = (-f-sqrt (delta))/(2 * e); Sol.push_back (p + v * t1); t2 = (-f + sqrt (delta))/(2 * e); Sol.push_back (p + v * T2); return 2;} /* Circle intersection */int getcirclecircleintersection (Circle O1, Circle O2, vector<point>& sol) {Double d = getlength (O1. O-O2.O); if (dcmp (d) = = 0) {if (dcmp (O1.R-O2.R) = = 0) Return-1;return 0;} if (dcmp (O1.R + o2.r-d) < 0) return 0;if (DCMP (fabs)-D) > 0) return O1.R-O2.R a = 0;double (Getangle) ;d ouble da = ACOs ((O1.R*O1.R + D*D-O2.R*O2.R)/(2*o1.r*d)); Point P1 = O1.point (a-da), p2 = O1.point (A+da), Sol.push_back (p1), if (P1 = = p2) return 1;sol.Push_back (p2); return 2;} /* tangents */int gettangents (point P, Circle O, vector* v) {Vector U = o.o-p;double d = getlength (u); if (d < O.R) R Eturn 0;else if (dcmp (D-O.R) = = 0) {V[0] = rotate (u, PI/2); return 1;} else {double ang = asin (O.R/D); v[0] = rotate (u ,-ang); v[1] = rotate (U, ANG); return 2;}} /* A[i] and b[i] are the tangency points of the section I tangent on O1 and O2 respectively */int gettangents (Circle O1, Circle O2, point* A, point* b) {int cnt = 0;IF (O1.R < O2.R) {swap (O1, O2); swap (A, b);} Double D2 = GetLength (O1.O-O2.O); D2 = D2 * d2;double rdif = O1.R-O2.R, rsum = O1.R + o2.r;if (D2 < RDIF * Rdif) return 0;if (dcmp (d2) = = 0 && DCMP (O1.R-O2.R) = = 0) return-1;double base = Getangle (O2.O-O1.O); if (dcmp (D2-RDIF * rdif) = = 0) {a[cnt] = O1.point ( Base); B[CNT] = O2.point (base); Cnt++;return CNT;} Double ang = ACOs ((O1.R-O2.R)/sqrt (D2)); a[cnt] = O1.point (Base+ang); B[CNT] = O2.point (Base+ang); CNT++;A[CNT] = O1.point (Base-ang); B[CNT] = O2.point (Base-ang); Cnt++;if (dcmp (d2-rsum * rsum) = =0) {a[cnt] = O1.point (base); b[cnt] = O2.point (base); cnt++;} else if (D2 > Rsum * rsum) {double ang = ACOs ((O1.R + O2 . R)/sqrt (D2)); a[cnt] = O1.point (Base+ang); B[CNT] = O2.point (Base+ang); CNT++;A[CNT] = O1.point (Base-ang); B[CNT] = O2.point (Base-ang); cnt++;} return CNT;} /* Three points to determine the tangent circle */circle circumscribedcircle (Point P1, Spot, point P3) {Double Bx = p2.x-p1.x, by = P2.Y-P1.Y; Double Cx = p3.x-p1.x, Cy = p3.y-p1.y; Double D = 2 * (Bx * cy-by * Cx); Double CX = (Cy * (BX * bx + by *) – by * (CX * CX + cy * cy))/D + p1.x; Double cy = (BX * (CX * CX + cy * CY)-CX * (BX * bx + by *))/D + p1.y; Point P = Point (CX, CY); Return Circle (P, GetLength (p1-p)); }/* three to determine inscribed circle */circle inscribedcircle (Point P1, points P2, dot p3) {Double A = GetLength (P2-P3); Double b = getlength (P3-P1); Double c = getlength (P1-P2); Point P = (P1 * A + P2 * b + p3 * c)/(A + B + c); Return Circle (P, Getdistancetoline (P, p1, p2)); }/* Triangle One vertex is the center */double getpubliCareatotriangle (Circle O, point A, point B) {if (dcmp ((A-O.O) * (b-o.o)) = = 0) return 0;int sig = 1;double da = getplength ( O.O-A), db = Getplength (O.o-b), if (dcmp (DA-DB) > 0) {swap (DA, db), swap (A, b); sig =-1;} Double T1, t2;vector<point> sol;int n = getlinecircleintersection (A, B, O, T1, T2, Sol); if (dcmp (DA-O.R*O.R) <= 0 {if (dcmp (DB-O.R*O.R) <= 0) return Getdirarea (O.O, A, b) * Sig;int k = 0;if (Getplength (sol[0]-b) > Getplength (sol[ 1]-b)) K = 1;double ret = Getarea (o.o, A, sol[k]) + O.getarea (Getangle (SOL[K]-O.O, b-o.o));d ouble tmp = (a-o.o) * (B-O.O); re TURN ret * SIG * DCMP (TMP);} Double d = getdistancetosegment (o.o, A, B), if (dcmp (D-O.R) >= 0) {DOUBLE ret = O.getarea (Getangle (A-O.O, b-o.o));d ouble TMP = (A-O.O) * (B-O.O); return ret * sig * DCMP (TMP);} Double K1 = o.r/getlength (a-o.o), K2 = O.r/getlength (B-O.O); Point P = o.o + (a-o.o) * K1, q = o.o + (b-o.o) * k2;double Ret1 = O.getarea (Getangle (P-O.O, q-o.o));d ouble Ret2 = o.g Etarea (Getangle (SOL[0]-O.O, SOL[1]-O.O)-Getarea (O.O, sol[0], sol[1]);d ouble ret = (ret1-ret2), TMP = (A-O.O) * (B-O.O); return ret * sig * DCMP (TMP); }double Getpublicareatopolygon (Circle O, point* p, int n) {if (dcmp (O.R) = = 0) return 0;double area = 0;for (int i = 0; i < n; i++) {int u = (i + 1)% n;area + = Getpublicareatotriangle (O, P[i], p[u]);} return Fabs (area);}}; Using namespace Polygonal;//void rotatingcalipersgetrectangle (point *p, int n, double& area, double& perimeter) { const int MAXN = 1e5 + 5;int N; Point P[MAXN], Ch[maxn];int main () {while (scanf ("%d", &n) = = 1 && N) {for (int i = 0; i < N; i++) p[i].re AD (); N = Getconvexhull (P, N, ch);d ouble area, Perimeter;rotatingcalipersgetrectangle (CH, n, area, perimeter);p rintf ("%.2lf%. 2lf\n ", area, perimeter);} return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
UVA 12307-smallest enclosing Rectangle (rotating jam)