按照劉汝佳老師說的,這道題本身沒有什麼演算法可言,
主要是考察選手對於幾何演算法的應用,
我們已經知道了點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 }