HDU 4998 Rotate (二维图形几何变换)

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 :).
 

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即绕点(x,y)旋转p度。
经过n次旋转后,相当于绕某个固定点旋转多少度,求固定点坐标和旋转度数。

解析:几何数学题,需要一个公式。

绕(xfyf)点的旋转变换

HDU 4998 Rotate (二维图形几何变换)_第1张图片

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;
}


你可能感兴趣的:(HDU,rotate,4998)