Rotate
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 573 Accepted Submission(s): 275
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
Source
Recommend
題意: 給你n個點和角度,平面以點爲中心,旋轉一個給定的角度。然後把它們合併成由一個點和角度旋轉而來,輸出這個點和角度。
思路
所以構造矩陣,來求最終旋轉角度,及2個點座標。平面上任意一個點(x,y)以點(x0,y0)爲中心旋轉p角度,得到一個新點(X,Y)。
所以新點公式:
X=(x-x0)*cos(p)-(y-y0)*sin(p)+x0;
Y=(x-x0)*sin(p)+(y-y0)*cos(p)+y0;
兩個未知數,兩個式子,很容易求出來。
2. 還有一種思路是 任取平面上兩個不同的點A1,A2,所以多次旋轉之後得到兩個點B1,B2,A1和B1的中垂線與A2和B2的中垂線的交點就是所求座標,角度也就很容易的處理。
下面貼一下思路1的AC代碼:
#include<stdio.h>
#include<math.h>
#include<string.h>
#define pi acos(-1.0)
#define ee 0.000001
struct Matrix
{
double a[2][2];
}m1,m2,m3; //定義的三個矩陣;
//矩陣乘法;
Matrix multi(Matrix a,Matrix b)
{
Matrix c;
int i,j,k;
for(i=0;i<2;i++)
for(j=0;j<2;j++)
{
c.a[i][j]=0;
for(k=0;k<2;k++)
c.a[i][j]+=a.a[i][k]*b.a[k][j];
}
return c;
}
int main()
{
int T,i,n;
double x,y,p,t,k1,k2;
double xx,yy;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
m3.a[0][0]=m3.a[1][1]=1;
m3.a[0][1]=m3.a[1][0]=0;
m1.a[0][0]=m1.a[1][0]=m1.a[0][1]=m1.a[1][1]=0;
for(i=0;i<n;i++)
{
scanf("%lf%lf%lf",&x,&y,&p);
t=2*pi;
while(p>=t)
p-=t;
m1.a[0][0]-=x;
m1.a[0][1]-=y;
m1.a[1][0]=m1.a[1][0]=0;
m2.a[0][0]=m2.a[1][1]=cos(p);
m2.a[0][1]=sin(p);
m2.a[1][0]=-sin(p);
m1=multi(m1,m2);
m1.a[0][0]+=x;
m1.a[0][1]+=y;
m3=multi(m3,m2);
}
k1=m1.a[0][0];
k2=m1.a[0][1];
t=acos(m3.a[0][0]);
if(sin(t)-m3.a[0][1]>ee) //防止精度損失;
t=2*pi-t;
//解二元一次方程;
yy=(k1*sin(t)+k2*(1-cos(t)))/(2-2*cos(t));
xx=(k1-yy*sin(t))/(1-cos(t));
printf("%.6lf %.6lf %.6lf\n",xx,yy,t);
}
return 0;
}