Rotate
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 297 Accepted Submission(s): 151
Special Judge
Problem 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 :).
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π.
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.
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即绕点(x,y)旋转p度。
经过n次旋转后,相当于绕某个固定点旋转多少度,求固定点坐标和旋转度数。
解析:几何数学题,需要一个公式。
绕(xf,yf)点的旋转变换
R代表 绕着(x,y)旋转θ度角。
R = R1 * R2 * ... * Rn
算出R的具体的值,代入公式并求解。
总结:这题对于精度的要求很严格,而且在求三角函数时,传是弧度,我传成角度了,样例一直出不来。
#include <cstring>
#include <cstdio>
#include <cmath>
#define N 100
#define PI acos(-1)
using namespace std;
int n;
struct Node {
double x,y,p;
}p[N],ans;
double mat[N][3][3];
void multi(double sum[][3],double a[][3]) {
double tmp[3][3];
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++) {
tmp[i][j] = 0;
}
}
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++) {
for(int k = 0; k < 3; k++) {
tmp[i][j] += sum[i][k] * a[k][j];
}
}
}
memcpy(sum,tmp,sizeof(tmp));
}
int main() {
int T;
double cosa,sina;
scanf("%d",&T);
while (T--) {
scanf("%d",&n);
ans.p = 0;
for (int i = 0; i < n; i++) {
scanf("%lf%lf%lf",&p[i].x,&p[i].y, &p[i].p);
ans.p += p[i].p;
if(ans.p >= 2 * PI) {
ans.p -= 2 * PI;
}
cosa = cos(p[i].p);
sina = sin(p[i].p);
mat[i][0][0] = cosa;
mat[i][0][1] = sina;
mat[i][0][2] = 0;
mat[i][1][0] = -sina;
mat[i][1][1] = cosa;
mat[i][1][2] = 0;
mat[i][2][0] = p[i].x * (1-cosa) + p[i].y * sina;
mat[i][2][1] = p[i].y * (1-cosa) - p[i].x * sina;
mat[i][2][2] = 1;
}
double sum[3][3];
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++) {
sum[i][j] = mat[0][i][j];
}
}
for(int i = 1; i < n; i++) {
multi(sum,mat[i]);
}
cosa = sum[0][0];
sina = sum[0][1];
double a,b,c,d;
a = 1 - cosa;
b = sina;
c = sum[2][0];
d = sum[2][1];
ans.x = (a*c - b*d) / (a*a + b*b);
ans.y = (c*b + a*d) / (a*a + b*b);
printf("%.10lf %.10lf %.10lf\n",ans.x,ans.y,ans.p);
}
return 0;
}