2013-08-23 17:41:53Morris
[UVA] 10577 - Bounding box
Problem C: Bounding box
Problem C: Bounding box |
The Archeologists of the Current Millenium (ACM) now and then discover ancient artifacts located at vertices of regular polygons. The moving sand dunes of the desert render the excavations difficult and thus once three vertices of a polygon are discovered there is a need to cover the entire polygon with protective fabric.
Input
Input contains multiple cases. Each case describes one polygon. It starts with an integer n1#150, the number of vertices in the polygon, followed by three pairs of real numbers giving the x and y coordinates of three vertices of the polygon. The numbers are separated by whitespace. The input ends with a n equal 0, this case should not be processed.
Output
For each line of input, output one line in the format shown below, giving the smallest area of a rectangle which can cover all the vertices of the polygon and whose sides are parallel to the x and y axes.
Sample Input
4 10.00000 0.00000 0.00000 -10.00000 -10.00000 0.00000 6 22.23086 0.42320 -4.87328 11.92822 1.76914 27.57680 23 156.71567 -13.63236 139.03195 -22.04236 137.96925 -11.70517 0
Sample Output
Polygon 1: 400.000 Polygon 2: 1056.172 Polygon 3: 397.673
Local_UVa'2003
給一個正 n 邊形的其中 3 個點,找到最小一個長方形包裹。
而這個長方形的邊要平行 x, y 軸。
先求外接圓半徑,以及外接圓圓心。
打算依序走訪整個正多邊形的所有點,從其中一個點出發,圓心 O,點 P。
拉向量 OP,旋轉 360度/n,得到下一個點 Q,依序找到所有點。
#include <stdio.h>
#include <algorithm>
#include <math.h>
using namespace std;
struct Pt {
double x, y;
};
Pt circle(Pt p1, Pt p2, Pt p3) {
double a, b, c, d, e, f;
double dx, dy, dd;
a = p1.x - p2.x, b = p1.y - p2.y;
c = a*((p1.x+p2.x)/2) + b*((p1.y+p2.y)/2);
d = p2.x - p3.x, e = p2.y - p3.y;
f = d*((p2.x+p3.x)/2) + e*((p2.y+p3.y)/2);
Pt o;
dd = a*e - b*d;
dx = c*e - b*f;
dy = a*f - d*c;
o.x = dx/dd, o.y = dy/dd;
return o;
}
int main() {
int n, cases = 0;
int i, j, k;
const double pi = acos(-1);
Pt a, b, c;
while(scanf("%d", &n) == 1 && n) {
scanf("%lf %lf", &a.x, &a.y);
scanf("%lf %lf", &b.x, &b.y);
scanf("%lf %lf", &c.x, &c.y);
Pt o = circle(a, b, c);
double theta = 2*pi/n;
double left, right, up, down;
left = down = 1e+30;
right = up = -1e+30;
Pt next, prev;
prev = a;
double sintheta = sin(theta);
double costheta = cos(theta);
for(i = 0; i < n; i++) {
double vx, vy, tx, ty;
vx = prev.x - o.x, vy = prev.y - o.y;
next.x = o.x + vx*costheta - vy*sintheta;
next.y = o.y + vx*sintheta + vy*costheta;
left = min(left, next.x), right = max(right, next.x);
down = min(down, next.y), up = max(up, next.y);
prev = next;
}
printf("Polygon %d: %.3lf\n", ++cases, (right-left)*(up-down));
}
return 0;
}