UVA - 11178 Morley's Theorem

自為風月馬前卒發表於2017-08-12

 

按照劉汝佳老師說的,這道題本身沒有什麼演算法可言,

主要是考察選手對於幾何演算法的應用,

我們已經知道了點A,B,C

如果要求點D的話

我們可以先求出向量C-B的座標,然後求出向量C-B與A-B的夾角。

再把夾角/3,這樣我們就找到了∠CBD的度數。

再把向量C-B逆時針旋轉∠CBD度

就求出了點D的座標,

E,F同理

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<cmath>
  5 #define Vector Point
  6 using namespace std;
  7 inline void read(int &n)
  8 {
  9     char c='+';bool flag=0;n=0;
 10     while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;}
 11     while(c>='0'&&c<='9')    n=n*10+(c-48),c=getchar();
 12     if(flag==1)n=-n;
 13 }
 14 const double PI=acos(-1);
 15 const double eps=1e-10;
 16 int dcmp(double x)    {return (fabs(x)<eps)?0:(x<0?-1:1);}
 17 struct Point
 18 {
 19     double x,y;
 20     Point(double x=0,double y=0):x(x),y(y){};
 21 };
 22 Vector operator + (Vector A,Vector B) {return Vector(A.x + B.x,A.y + B.y);}
 23 Vector operator - (Vector A,Vector B) {return Vector(A.x - B.x,A.y - B.y);}
 24 Vector operator * (Vector A,double P) {return Vector(A.x * P,A.y * P);}
 25 Vector operator / (Vector A,double P) {return Vector(A.x / P,A.y / P);}
 26 bool operator < (const Point &a,const Point &b){return a.x < b.x || (a.x == b.x && a.y < b.y);}
 27 bool operator == (const Point &a,const Point &b){return dcmp(a.x - b.x)==0 && dcmp(a.y - b.y)==0;}
 28 
 29 double Dot(Vector A,Vector B){return A.x * B.x + A.y * B.y;}//點積 ********************
 30 double Length(Vector A){return sqrt(Dot(A,A));}// 求向量的長度 
 31 double Angle(Vector A,Vector B){return acos(Dot(A,B) / (Length(A)) / Length(B));} //求兩個向量的夾角 
 32 
 33 double Cross(Vector A,Vector B){return A.x * B.y-A.y * B.x;}// 兩個向量的叉積 
 34 double Area2(Point A,Point B,Point C){return Cross(B - A,C - A);}
 35 
 36 Vector Rotate(Vector A,double rad){return Vector(A.x * cos(rad)-A.y * sin(rad),A.x * sin(rad)+A.y * cos(rad));}// 向量旋轉********* 
 37 
 38 Point GetLineIntersection(Point P,Point v,Point Q,Point w)// 兩直線的交點 ****************
 39 {
 40     Vector u=P-Q;
 41     double t=Cross(w,u)/Cross(v,w);
 42     return P+v*t;
 43 }
 44 
 45 double DistanceToLine(Point P,Point A,Point B)// 點P到直線AB的距離 
 46 {
 47     Vector v1=B - A;Vector v2= P-A;
 48     return fabs(Cross(v1,v2)) / Length(v1);
 49 }
 50 
 51 double DistanceToSegment(Point P,Point A,Point B)// 點P到線段AB的距離 
 52 {
 53     if(A==B)    return Length(P-A);
 54     Vector v1=B-A, v2=P-A, v3=P-B;
 55     if(dcmp(Dot(v1,v2)) < 0)    return Length(v2);
 56     else if(dcmp(Dot(v1,v3)) > 0)    return Length(v3);// 怎麼會是大於。。。。。。
 57     else return fabs(Cross(v1,v2)) / Length(v1);        
 58 }
 59 
 60 Point GetLineProjection(Point P, Point A, Point B)// 求點P在直線AB上的正投影 
 61 {
 62     Vector v=B-A;
 63     return A+v*(Dot(v, P-A) / Dot(v,v));
 64 }
 65 
 66 bool SegmentProperIntersection(Point a1, Point a2, Point b1,Point b2)//判斷兩直線是否相交 
 67 {
 68     double c1 = Cross(a2-a1,b1-a1) , c2 = Cross(a2-a1,b2-a1),
 69            c3 = Cross(b2-b1,a1-b1) , c4 = Cross(b2-b1,a2-b1);
 70     return dcmp(c1)*dcmp(c2)<0 && dcmp(c3)*dcmp(c4)<0;
 71 }
 72 
 73 double PolygonArae(Point *p,int n)// 求多邊形的有向面積 
 74 {
 75     double area = 0;
 76     for(int i=1;i<=n-1;i++)
 77         area += Cross(p[i]-p[0],p[i+1]-p[0]);
 78     return area/2;
 79 }
 80 Point read_point()
 81 {
 82     double x,y;
 83     scanf("%lf%lf",&x,&y);
 84     return Point(x,y);
 85 }
 86 Point getans(Point A,Point B,Point C)
 87 {
 88     Vector v1= C-B;
 89     double ang1=Angle(A-B,v1);
 90     v1=Rotate(v1,ang1/3);
 91     
 92     Vector v2= B-C;
 93     double ang2=Angle(A-C,v2);
 94     v2=Rotate(v2,-ang2/3);
 95     
 96     return GetLineIntersection(B,v1,C,v2);
 97 }
 98 int main()
 99 {
100     int T;read(T);
101     while(T--)
102     {
103         Point A,B,C,D,E,F;
104         A=read_point();
105         B=read_point();
106         C=read_point();
107         D=getans(A,B,C);
108         E=getans(B,C,A);
109         F=getans(C,A,B);
110         printf("%.6lf %.6lf %.6lf %.6lf %.6lf %.6lf\n", D.x, D.y, E.x, E.y, F.x, F.y);
111     }
112     
113     return 0;
114 }

 

相關文章