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
| #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 arc, pol, R[MAXN], A[MAXN], B[MAXN];
vector< pair<double, double> > seg, cover;
inline void getarea(const int i, const double lef, const double rig)
{
arc += 0.5 * 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);
pol += 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 j = 0; j < i; ++j)
if (!sign(R[i]-R[j]) && !sign(A[i]-A[j]) && !sign(B[i]-B[j]))
{
R[i] = .0;
break;
}
}
for (int i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
if (i != j && sign(R[j]-R[i]) >= 0 && sign(dist(A[i], B[i], A[j], B[j])-(R[j]-R[i])) <= 0)
{
covered[i] = true;
break;
}
for (int i = 0; i < n; ++i) if (sign(R[i]) && !covered[i])
{
seg.clear();
for (int j = 0; j < n; ++j) if (i != j && sign(R[i]) && !covered[i])
{
const double d = dist(A[i], B[i], A[j], B[j]);
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]);
const pair<double, double> tmp(alpha-beta, alpha+beta);
if (sign(tmp.first) <= 0 && sign(tmp.second) <= 0)
seg.push_back(pair<double, double>(2*PI+tmp.first, 2*PI+tmp.second));
else if (sign(tmp.first) < 0)
{
seg.push_back(pair<double, double>(2*PI+tmp.first, 2*PI));
seg.push_back(pair<double, double>(0, tmp.second));
}
else
seg.push_back(tmp);
}
std::sort(seg.begin(), seg.end());
double rig = 0;
for (vector< pair<double, double> >::iterator iter = seg.begin(); iter != seg.end(); ++iter)
{
if (sign(rig - iter->first) >= 0)
rig = std::max(rig, iter->second);
else
{
getarea(i, rig, iter->first);
rig = iter->second;
}
}
if (!sign(rig))
arc += R[i]*R[i]*PI;
else
getarea(i, rig, 2*PI);
}
printf("%.3f", pol/2.0 + arc);
}
|