1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
| #include <cmath>
#include <cstdio>
#include <vector>
#include <algorithm>
using std::pair;
using std::vector;
inline double sqr(const double x) { return x*x; }
inline double dist(const double x1, const double y1, const double x2, const double y2)
{ return std::sqrt(sqr(x1-x2) + sqr(y1-y2)); }
inline double angle(const double A, const double B, const double C)
{ return std::acos((sqr(A)+sqr(B)-sqr(C))/(2*A*B)); }
inline int sign(const double x)
{
static const double EPS = 1e-8;
if (x > EPS) return 1;
return x < -EPS ? -1 : 0;
}
const int MAXN = 1000;
const double PI = std::acos(-1.0);
int n;
bool covered[MAXN];
double R[MAXN], A[MAXN], B[MAXN], ans[MAXN];
vector< pair<double, double> > cover;
vector< pair<double, int> > bracket;
inline double getarea(const int i, const double lef, const double rig)
{
double res = R[i] * R[i] * (rig-lef - std::sin(rig-lef));
const double x1 = A[i] + R[i] * std::cos(lef), y1 = B[i] + R[i] * std::sin(lef);
const double x2 = A[i] + R[i] * std::cos(rig), y2 = B[i] + R[i] * std::sin(rig);
return res + x1*y2 - x2*y1;
}
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; ++i)
scanf("%lf%lf%lf", A+i, B+i, R+i);
for (int i = 0; i < n; ++i)
{
bracket.clear();
int cover = 0;
for (int j = 0; j < n; ++j) if (i != j)
{
const double d = dist(A[i], B[i], A[j], B[j]);
if (sign(R[j]-R[i]) >= 0 && sign(d-(R[j]-R[i])) <= 0)
{ ++cover; continue; }
else if (sign(d-(R[j]+R[i])) >= 0 || sign(d-std::abs(R[j]-R[i])) <= 0)
continue;
const double alpha = std::atan2(B[j]-B[i], A[j]-A[i]);
const double beta = angle(R[i], d, R[j]);
pair<double, double> tmp(alpha-beta, alpha+beta);
if (sign(tmp.first) <= 0 && sign(tmp.second) <= 0)
tmp.first += 2*PI, tmp.second += 2*PI;
if (sign(tmp.first) < 0)
{
bracket.push_back(pair<double, int>(2*PI+tmp.first, 1));
bracket.push_back(pair<double, int>(2*PI, -1));
bracket.push_back(pair<double, int>(0, 1));
bracket.push_back(pair<double, int>(tmp.second, -1));
}
else
{
bracket.push_back(pair<double, int>(tmp.first, 1));
bracket.push_back(pair<double, int>(tmp.second, -1));
}
}
if (bracket.empty())
{
const double s = 2.0 * PI * R[i] * R[i];
ans[cover] -= s;
ans[cover+1] += s;
continue;
}
bracket.push_back(pair<double, int>(0, 0));
bracket.push_back(pair<double, int>(2*PI, 0));
std::sort(bracket.begin(), bracket.end());
int stack = cover;
for (vector< pair<double, int> >::iterator iter = bracket.begin(); iter != bracket.end()-1; ++iter)
{
stack += iter->second;
const double s = getarea(i, iter->first, (iter+1)->first);
ans[stack] -= s;
ans[stack+1] += s;
}
}
for (int i = 1; i <= n; ++i)
printf("[%d] = %.3f\n", i, ans[i]/2.0);
}
|