思路:构造一个多边形,顶点集由边界顶点和旋转中心点组成。将此多边形绕每个中心点旋转相应角度,得到新的多边形,任取原多边形和新多边形的两条对应边,分别作中垂线,直到两中垂线平行为止。两中垂线的交点即为旋转中心A,旋转角p为每个旋转角的和,注意将其对2π取模,p = fmod(p, 2*acos(-1.0));
//Rotate.cpp
#include <ios>
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <cstdio>
#include <cwchar>
#include <iosfwd>
#include <limits>
#include <locale>
#include <memory>
#include <string>
#include <vector>
#include <cassert>
#include <ciso646>
#include <climits>
#include <clocale>
#include <complex>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <cwctype>
#include <fstream>
#include <iomanip>
#include <istream>
#include <numeric>
#include <ostream>
#include <sstream>
#include <utility>
#include <iostream>
#include <iterator>
#include <valarray>
#include <algorithm>
#include <exception>
#include <stdexcept>
#include <streambuf>
#include <functional>
#define LL long long
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define PI 3.1415926535897932626
#define mid(n) ((center[n]+pol.a[n])*0.5)
#define CLEAR(name, init) memset(name, init, sizeof(name))
const double eps = 1e-8;
const int MAXN = (int)1e9 + 5;
using namespace std;
struct Point {
double x, y;
Point(double x = 0.0, double y = 0.0): x(x), y(y) { }
};
struct Polygon {
int n;
Point a[20];
Polygon() {}
};
typedef Point Vector;
Vector operator + (Vector A, Vector B) { return Vector(A.x+B.x, A.y+B.y); }
Vector operator - (Point A, Point B) { return Vector(A.x-B.x, A.y-B.y); }
Vector operator * (Vector A, double p) { return Vector(A.x*p, A.y*p); }
Vector operator / (Vector A, double p) { return Vector(A.x/p, A.y/p); }
double Dot(Vector A, Vector B) { return A.x*B.x + A.y*B.y; }
double Length(Vector A) { return sqrt(Dot(A, A)); }
double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; }
Point rotate(Vector A, double alpha) {
double cos_rad = cos(alpha), sin_rad = sin(alpha);
return Vector(A.x*cos_rad-A.y*sin_rad, A.x*sin_rad+A.y*cos_rad);
}
Point GetLineIntersection(Point P, Vector v, Point Q, Vector w) {
Vector u = P - Q;
double t = Cross(w, u) / Cross(v, w);
return P + v*t;
}
struct line {
Point a,b;
line(){}
line(Point x,Point y):a(x),b(y){}
};
int dblcmp(double x) {
if (fabs(x) < eps) return 0;
return x > 0 ? 1 : -1;
}
bool parallel(line a,line b) {
return !dblcmp(Cross(a.a-a.b,b.a-b.b));
}
int main(int argc, char const *argv[]) {
#ifndef ONLINE_JUDGE
freopen("D:\\Documents\\Programs\\Acm\\input.txt", "r", stdin);
#endif
int T; cin >> T;
while(T--) {
int n; cin >> n;
Point left_up = Point(0.0, 100.0);
Point right_up = Point(100.0, 100.0);
Point left_down = Point(0.0, 0.0);
Point right_down = Point(100.0, 0.0);
Polygon pol;
pol.n = n + 4;
pol.a[0] = left_up; pol.a[1] = right_up;
pol.a[2] = left_down; pol.a[3] = right_down;
Point center[20];
double rad[20], p = 0.0;
for(int i = 0; i < n; i++) {
scanf("%lf%lf%lf", ¢er[i+4].x, ¢er[i+4].y, &rad[i+4]);
pol.a[i+4] = center[i+4];
p += rad[i+4];
}
for(int i = 0; i < 4; i++) center[i] = pol.a[i];
while(p >= 2*acos(-1.0)) p -= 2*acos(-1.0);
for(int i = 4; i < pol.n; i++) {
for(int j = 0; j < pol.n; j++) {
pol.a[j] = rotate(pol.a[j]-center[i], rad[i]) + center[i];
}
}
Point res;
for (int i = 0; i < pol.n; i++) {
for (int j = i+1; j < pol.n; j++) {
Point p1 = (center[i]+pol.a[i]) * 0.5;
Point q1 = (center[j]+pol.a[j]) * 0.5;
Point p2 = rotate(center[i]-p1, PI/2.0)+p1;
Point q2 = rotate(center[j]-q1, PI/2.0)+q1;
line P = line(p1, p2), Q = line(q1, q2);
if (parallel(P,Q)) continue;
double s1=Cross(p1-q1, q2-q1);
double s2=Cross(p2-q1, q2-q1);
res = (p2*s1-p1*s2)/(s1-s2);
}
}
printf("%.10lf %.10lf %.10lf\n", res.x, res.y, p);
}
return 0;
}