题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4998
Description
Noting is more interesting than rotation!
Your little sister likes to rotate things. To put it easier to analyze, your sister makes n rotations. In the i-th time, she makes everything in the plane rotate counter-clockwisely around a point ai by a radian of pi.
Now she promises that the total effect of her rotations is a single rotation around a point A by radian P (this means the sum of pi is not a multiplier of 2π).
Of course, you should be able to figure out what is A and P :).
Input
The first line contains an integer T, denoting the number of the test cases.
For each test case, the first line contains an integer n denoting the number of the rotations. Then n lines follows, each containing 3 real numbers x, y and p, which means rotating around point (x, y) counter-clockwisely by a radian of p.
We promise that the sum of all p's is differed at least 0.1 from the nearest multiplier of 2π.
T<=100. 1<=n<=10. 0<=x, y<=100. 0<=p<=2π.
Output
For each test case, print 3 real numbers x, y, p, indicating that the overall rotation is around (x, y) counter-clockwisely by a radian of p. Note that you should print p where 0<=p<2π.
Your answer will be considered correct if and only if for x, y and p, the absolute error is no larger than 1e-5.
Sample Input
1
3
0 0 1
1 1 1
2 2 1
Sample Output
1.8088715944 0.1911284056 3.0000000000
题意:
平面内一个图形,给你n次旋转。每次围绕(x,y)逆时针旋转p度。问最终这个图形可以转换成围绕某点逆时针旋转多少度。
题解:
任意假设两个不同的点,依次模拟旋转n次后的点的位置。分别连接两点的旋转前和旋转后。作中垂线。交点就是我们要求的围绕旋转点。再通过余弦定理求角度。注意可能大于半园。需要最后将p代入判断是否满足。不满足则是2π-p。
代码:
#include <bits/stdc++.h>
using namespace std;
struct Point {
double x,y ;
} ;
struct Rotate {
double x,y,p ;
} ;
Rotate r[20] ;
int n ;
Point zhuan(Point a,Rotate b) {
double co,si ;
co = cos(b.p) ; si = sin(b.p) ;
Point ans;
ans.x = (a.x-b.x)*co - (a.y-b.y)*si + b.x ;
ans.y = (a.y-b.y)*co + (a.x-b.x)*si + b.y ;
return ans;
}
double dis(Point a,Point b){
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)) ;
}
const double eps = 1e-8 ;
double getp(Point d,Point x1,Point x2){
double d1 = dis(d,x1) ;
double d2 = dis(x1,x2) ;
return acos((2*d1*d1-d2*d2)/(2*d1*d1)) ;
}
int main()
{
int t;
scanf("%d",&t) ;
while (t--){
scanf("%d",&n) ;
Point x1,x2,x3,x4 ;
x1 = {0,1} ;
x2 = {1,0} ;
x3 = x1 ;
x4 = x2 ;
for (int i = 1; i <= n; i++){
scanf("%lf %lf %lf",&r[i].x,&r[i].y,&r[i].p) ;
x3 = zhuan(x3,r[i]) ;
x4 = zhuan(x4,r[i]) ;
}
double ax,ay,p ;
if ((fabs(x1.x-x3.x) < eps)&&(fabs(x1.y-x3.y) < eps)){
ax = x1.x ; ay = x1.y ; p = getp(x1,x2,x4) ;
}else if ((fabs(x2.x-x4.x) < eps)&&(fabs(x2.y-x4.y) < eps)) {
ax = x2.x ; ay = x2.y ; p = getp(x2,x1,x3) ;
}else {
double k1,k2,b1,b2 ;
k1 = -(x1.x-x3.x)/(x1.y-x3.y) ;
k2 = -(x2.x-x4.x)/(x2.y-x4.y) ;
b1 = ((x1.x*x1.x-x3.x*x3.x) + (x1.y*x1.y-x3.y*x3.y))/(2.0*(x1.y-x3.y)) ;
b2 = ((x2.x*x2.x-x4.x*x4.x) + (x2.y*x2.y-x4.y*x4.y))/(2.0*(x2.y-x4.y)) ;
ax = (b2-b1)/(k1-k2) ;
ay = k1*ax + b1 ;
Point te={ax,ay} ;
p = getp(te,x1,x3) ;
}
Rotate fuck = {ax,ay,p} ;
Point ansfuck = zhuan(x1,fuck) ;
if (!((fabs(x3.x-ansfuck.x)<eps)&&(fabs(x3.y-ansfuck.y)<eps)))
p = 2.0*acos(-1.0)-p ;
printf("%.7lf %.7lf %.7lf\n",ax,ay,p) ;
}
return 0 ;
}