UVA11178 Morley's Theorem 题解
Hello World
计算几何第一题,涉及两个方面的应用。
向量的旋转:
向量 \(\vec{a}=(x,y)\) 逆时针旋转 \(\alpha\) 得到的向量为 \((x\cos \alpha-y\sin \alpha,x\sin \alpha +y \cos \alpha)\)。这个比较难记,可以理解为矩阵乘法的结果。
\[ \begin{bmatrix}x & y\end{bmatrix} \times\begin{bmatrix} \cos\alpha & \sin\alpha \\ -\sin\alpha & \cos\alpha \end{bmatrix}
\]
直线交点的求法:
考虑两条直线 \(l_1 = P+t\vec{v},l_2=Q+\mu \vec{w}\)。由于交于同一点,有方程:
\[P+t\vec{v}=Q+\mu \vec{w}
\]
两边同时叉 \(\vec{w}\):
\[(P+t\vec{v})\times \vec{w} = (Q+\mu \vec{w}) \times \vec{w}
\]
展开,移项,由于 \(\vec{w}\times \vec{w} = 0\):
\[t\vec{v}\times \vec{w} = (Q-P) \times \vec{w}
\]
得到
\[t= \frac{(Q-P)\times \vec{w}}{\vec{v} \times \vec{w}}
\]
这样就得到了直线的交点公式。
这道题目也就迎刃而解,根据题目求出角度值模拟即可。
#include <bits/stdc++.h>
#ifndef ONLINE_JUDGE
#include <debug.h>
#endif
#define pii pair<int,int>
#define all(x) x.begin(),x.end()
#define ull unsigned long long
#define uint unsigned int
#define rg register
#define il inline
#define rep(i,a,b) for(rg int i=(a);i<=(b);++i)
#define sqr(x) ((x)*(x))
using namespace std;
const int INF=0x3f3f3f3f;
inline int read()
{
int w=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
w=(w<<1)+(w<<3)+(ch^48);
ch=getchar();
}
return w*f;
}
inline void write(int x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9) write(x/10);
putchar(x%10+'0');
}
const double eps=1e-8;
struct point
{
double x,y;
point(double _x=0,double _y=0):x(_x),y(_y){}
friend point operator +(point a,point b)
{
return point(a.x+b.x,a.y+b.y);
}
friend point operator -(point a,point b)
{
return point(a.x-b.x,a.y-b.y);
}
friend point operator *(point a,double b)
{
return point(a.x*b,a.y*b);
}
friend point operator /(point a,double b)
{
return point(a.x/b,a.y/b);
}
};
point rotate(point a,double alpha)
{
return point(a.x*cos(alpha)-a.y*sin(alpha),a.x*sin(alpha)+a.y*cos(alpha));
}
double dot(point a,point b)
{
return a.x*b.x+a.y*b.y;
}
double cross(point a,point b)
{
return a.x*b.y-a.y*b.x;
}
double len(point a)
{
return sqrt(sqr(a.x)+sqr(a.y));
}
double dist(point a,point b)
{
return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
}
double angle(point a,point b)
{
return acos(dot(a,b)/len(a)/len(b));
}
typedef point vec;
struct line
{
point A,B;
line(point _A=point(0,0),point _B=point(0,0)):A(_A),B(_B){}
};
point intersec(line a,line b)
{
double t=cross(b.A-a.A,b.B)/cross(a.B,b.B);
return a.A+a.B*t;
}
typedef line segment;
struct circle
{
point p;double r;
circle(point _p=point(0,0),double _r=0):p(_p),r(_r){};
};
int T;
point A,B,C;
point calc(point A,point B,double theta1,double theta2)
{
vec A1=B-A,B1=A-B;
vec A2=rotate(A1,theta1/3.0),B2=rotate(B1,-theta2/3.0);
line l1=line(A,A2),l2=line(B,B2);
return intersec(l1,l2);
}//求出A逆时针,B顺时针的交点
int main()
{
#ifndef ONLINE_JUDGE
//freopen("in.txt","r",stdin);
#endif
T=read();
while(T--)
{
A.x=read(),A.y=read();
B.x=read(),B.y=read();
C.x=read(),C.y=read();
double theta1=angle(B-A,C-A),theta2=angle(A-B,C-B),theta3=angle(B-C,A-C);
point F=calc(A,B,theta1,theta2),D=calc(B,C,theta2,theta3),E=calc(C,A,theta3,theta1);
printf("%.6lf %.6lf %.6lf %.6lf %.6lf %.6lf\n",D.x,D.y,E.x,E.y,F.x,F.y);
}
return 0;
}

浙公网安备 33010602011771号