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

posted @ 2025-04-09 20:46  vanueber  阅读(26)  评论(0)    收藏  举报