您的位置:首页 > 其它

HDU 4998 Rotate 平面旋转

2014-10-15 14:25 393 查看


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


[align=left]Problem Description[/align]
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 :).

 

[align=left]Input[/align]
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π.
 

[align=left]Output[/align]
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.

 

[align=left]Sample Input[/align]

1
3
0 0 1
1 1 1
2 2 1

 

[align=left]Sample Output[/align]

1.8088715944 0.1911284056 3.0000000000

 

[align=left]Source[/align]
2014 ACM/ICPC Asia Regional Anshan Online

 

[align=left]Recommend[/align]
hujie   |   We have carefully selected several similar problems for you:  5065 5064 5063 5062 5061 

题意: 给你n个点和角度,平面以点为中心,旋转一个给定的角度。然后把它们合并成由一个点和角度旋转而来,输出这个点和角度。

思路
1. 由平面旋转知识:http://blog.csdn.net/wcyoot/article/details/33310329
    所以构造矩阵,来求最终旋转角度,及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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  计算几何