Rotate
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4998
题目意思:
平面上有一个二维坐标轴上,进行n次操作,把坐标轴绕着(x,y) (这个坐标总是初始坐标轴的坐标) 逆时针转p弧度。最后的结果相当于进行一次操作,即绕着(X, Y) 逆时针旋转了P弧度。求 X,Y,P,题目保证总有解.
解题思路:
不难发现,最后的P是n次的p的和,因为这和绕什么点旋转无关。(在草稿纸上画一个图理解一下吧)
至于求最后C点的坐标,那就简单了。
此题相当于是一个模板题,模板:http://blog.csdn.net/piaocoder/article/details/39255451
对任意点x1,x2,绕一个坐标点v逆时针旋转p角度后的新的坐标设为t1,t2,x1=t1,x2=t2;
循环上述操作,得到最后的 x1,x2;令x3等于最开始的x1,x4等于最开始的x2;最后点C的坐标,即为直线x1x3的垂直平分线与直线x2x4的垂直平分线的交点。
AC代码:
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
模板函数
struct Point{
double x,y;
Point(double x=0,double y=0):x(x),y(y) {}
};
typedef Point Vector;
const double pi=4*atan(1.0);
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,t;
Point v,t1,t2,t3,t4;
Vector a,b,tmp1,tmp2;
double p;
double x,y,p1=0;
t1.x=t1.y=t3.x=t3.y=0,t2.x=t2.y=t4.x=t4.y=1;
Point a1,a2,c;
scanf("%d",&n);
for(int i = 0; i < n; i++){
scanf("%lf%lf%lf",&v.x,&v.y,&p);
tmp1 = t1-v;
tmp2 = t2-v;
t1 = Rotate(tmp1,p)+v;
t2 = Rotate(tmp2,p)+v;
//printf("%.10lf %.10lf \n",t1.x,t1.y);
p1 += p;
}
t = p1/(2*pi);
p1 -= t*(2*pi);
a1 = (t1+t3)/2;a2=(t2+t4)/2;
a = t1-t3;b=t2-t4;
a = Normal(a);b = Normal(b);
c = getlineintersection(a1,a,a2,b);
printf("%.10lf %.10lf %.10lf\n",c.x,c.y,p1);
}
return 0;
}