题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4998
解题思路:
题目大意:给定n个点和n个角度,平面内任意一个点依次以这些点Point(i)为旋转中心,逆时针旋转 R(i)度,求最后相当于绕哪个点旋转多少度,求这个点的坐标以及旋转的角度。
算法思想:
一个点(x,y)绕另外一个点(x0,y0)旋转 r0 度的公式为:
x1= (x - x0)*cos(r0) - (y - y0)*sin(r0) + x0 ;
y1= (x - x0)*sin(r0) + (y - y0)*cos(r0) + y0 ;
最后旋转点肯定是xx,tmp1的垂直平分线以及由yy,tmp2的垂直平分线的交点,旋转角度rad = (r1+r2+.....+rn)%(2*pi)。
最后直接套模板即可。。。http://blog.csdn.net/piaocoder/article/details/47403265
AC代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const double eps = 1e-5;
const double pi = acos(-1.0);
struct Point{
double x,y;
Point(double x = 0,double y = 0):x(x),y(y){} // 构造函数,方便代码编写
};
typedef Point Vector;
Vector operator + (Vector A,Vector B){
return Vector(A.x+B.x,A.y+B.y);
}
Vector operator - (Vector A,Vector B){
return Vector(A.x-B.x,A.y-B.y);
}
Vector operator * (Vector A,double p){
return Vector(A.x*p,A.y*p);
}
Vector operator / (Vector A,double p){
return Vector(A.x/p,A.y/p);
}
double Dot(Vector A,Vector B){
return A.x*B.x+A.y*B.y;
}
double Length(Vector A){
return sqrt((Dot(A,A)));
}
double Cross(Vector A,Vector B){
return A.x*B.y-A.y*B.x;
}
Vector Rotate(Vector A,double rad){
return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
Vector Normal(Vector A){
double L = Length(A);
return Vector(-A.y/L,A.x/L);
}
Point GetLineIntersection(Point P,Vector v,Point Q,Vector w){
Vector u = P-Q;
double t = Cross(w,u)/Cross(v,w);
return P+v*t;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
Point xx(-1,0),yy(1,0);
Point tmp1 = xx,tmp2 = yy,tmp3;
double x, rad = 0;
for(int i = 0; i < n; i++){
scanf("%lf%lf%lf",&tmp3.x,&tmp3.y,&x);
tmp1 = Rotate(tmp1-tmp3,x)+tmp3;
tmp2 = Rotate(tmp2-tmp3,x)+tmp3;
rad += x;
}
Point tt1 = (xx+tmp1)/2, tt2 = (yy+tmp2)/2;
Vector v1,v2;
v1 = Normal(tmp1-xx);v2 = Normal(tmp2-yy);
Point ans = GetLineIntersection(tt1,v1,tt2,v2);
while(rad > 2*pi)
rad -= 2*pi;
printf("%.10lf %.10lf %.10lf\n",ans.x,ans.y,rad);
}
return 0;
}