一个简单的几何题,比赛时把公式写错了,都比了好久,还好看出来了
就是任意选择两个点按照n次旋转之后求两条线段的中垂线的交点就是旋转中心点了,角度用余弦定理就ok。。完全不卡精度啊。。。
#include<iostream>
#include<sstream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<time.h>
#include<set>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
#define inf 6000000000
#define lc l,m,index<<1
#define rc m+1,r,index<<01|1
#define max_n 100005
#define mod 1000000007
#define FOR(i,s,t) for(int i=(s);i<=(t);++i)
#define LL __int64
const double pi=acos(-1.0);
struct P
{
double x,y,p;
}a[max_n];
P rotate(P q,double x0,double y0,double ang)
{
P ans;
double cosa=cos(ang);
double sina=sin(ang);
double dx=q.x-x0;
double dy=q.y-y0;
ans.x=cosa*dx-sina*dy+x0;
ans.y=sina*dx+cosa*dy+y0;
return ans;
}
double dis(P a,P b)
{
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
double det(P a,P b,P c)
{
return (a.x-b.x)*(c.y-b.y)-(a.y-b.y)*(c.x-b.x);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
P p,q,m,s;
P p1,q1,m1,s1;
p.x=110;p.y=120;
p1.x=130;p1.y=150;
q=p;
q1=p1;
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].p);
for(int i=0;i<n;i++)
{
p=rotate(p,a[i].x,a[i].y,a[i].p);
p1=rotate(p1,a[i].x,a[i].y,a[i].p);
}
m.x=(q.x+p.x)/2;
m.y=(q.y+p.y)/2;
m1.x=(q1.x+p1.x)/2;
m1.y=(q1.y+p1.y)/2;
double A,B,A1,B1,C;
A=p.x-q.x;
B=p.y-q.y;
A1=p1.x-q1.x;
B1=p1.y-q1.y;
P r;
r.x=(B1*(A*m.x+B*m.y)-B*(A1*m1.x+B1*m1.y))/(A*B1-B*A1);
r.y=(A*m.x+B*m.y-A*r.x)/B;
double lll;
A=dis(r,q);
B=dis(r,p);
C=dis(q,p);
lll=A+B-C;
lll=lll/(2.0*sqrt(A*B));
//printf("%lf %lf\n",lll,acos(lll));
if(det(q,p,r)>0)
r.p=2*pi-acos(lll);
else
r.p=acos(lll);
printf("%.10lf %.10lf %.10lf\n",r.x,r.y,r.p);
}
return 0;
}