您的位置:首页 > 其它

【UVA11178】Morley's Theorem——Morley 定理

2016-04-08 10:43 309 查看
Morleys theorem states that that the lines

trisecting the angles of an arbitrary plane

triangle meet at the vertices of an equilateral

triangle. For example in the figure

below the tri-sectors of angles A, B and C

has intersected and created an equilateral

triangle DEF.



Of course the theorem has various generalizations,

in particular if all of the trisectors

are intersected one obtains four

other equilateral triangles. But in the

original theorem only tri-sectors nearest

to BC are allowed to intersect to get point

D, tri-sectors nearest to CA are allowed to intersect point E and tri-sectors nearest to AB are intersected

to get point F. Trisector like BD and CE are not allowed to intersect. So ultimately we get only

one equilateral triangle DEF. Now your task is to find the Cartesian coordinates of D, E and F given

the coordinates of A, B, and C.

Input

First line of the input file contains an integer N (0 < N < 5001) which denotes the number of

test cases to follow. Each of the next lines contain six integers XA, YA, XB, YB, XC , YC . This six

integers actually indicates that the Cartesian coordinates of point A, B and C are (XA, YA),(XB, YB)

and (XC , YC ) respectively. You can assume that the area of triangle ABC is not equal to zero, 0 ≤

XA, YA, XB, YB, XC , YC ≤ 1000 and the points A, B and C are in counter clockwise order.

Output

For each line of input you should produce one line of output. This line contains six floating point

numbers XD, YD, XE, YE, XF , YF separated by a single space. These six floating-point actually means

that the Cartesian coordinates of D, E and F are (XD, YD),(XE, YE) ,(XF , YF ) respectively. Errors

less than 10−5 will be accepted.

Sample Input

2

1 1 2 2 1 2

0 0 100 0 50 50

Sample Output

1.316987 1.816987 1.183013 1.683013 1.366025 1.633975

56.698730 25.000000 43.301270 25.000000 50.000000 13.397460

题意:三角形每个内角的三等分线相交的三角形为等边三角形,求交点坐标。

分析:向量旋转和直线的相交。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <iostream>

using namespace std;

const double eps = 1e-6;

const double PI = acos(-1.0);

typedef struct Point
{
double x,y;

Point(double x= 0 ,double y = 0 ):x(x),y(y){}

Point operator + (const Point &a)const {return Point(a.x+x,y+a.y);}

Point operator - (const Point &a)const {return Point(x-a.x,y-a.y);}

Point operator * (const double &a)const {return Point(x*a,y*a);}

Point operator / (const double &a)const {return Point(x/a,y/a);}

bool operator < (const Point &a)const {return x<a.x||(x==a.x&&y<a.y);}

}Vector;

int dbcmp(double x)
{
if(fabs(x)<eps) return 0;

return x>0?1:-1;
}

bool operator == (const Point &a,const Point  b) //判断点的相等
{
return dbcmp(a.x-b.x)==0 && dbcmp(a.y-b.y)==0;
}

double Dot(Vector A,Vector B) {return A.x*B.x+A.y*B.y;} //点积

double Cross(Vector A,Vector B) {return A.x*B.y-A.y*B.x;} //叉积

double Length(Vector A) {return sqrt(Dot(A,A));}//向量长度

double Angle(Vector A,Vector B) {return acos(Dot(A,B)/Length(A)/Length(B));}//向量之间的夹角

double Area2(Point A,Point B,Point C) {return Cross(B-A,C-A);} //求平行四边形面积

Vector Rotate (Vector A,double rad) {return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));} //二维向量逆时针旋转rad

Point GetLineIntersection(Point P,Vector v,Point Q,Point w) //求两直线Pv,Qw交点,保证直线只有唯一的一个交点。
{
Vector u = P-Q;

double t = Cross(w,u)/Cross(v,w);

return P+v*t;
}

double DistanceToLine(Point P,Point A,Point B) //点P到直线AB的距离
{
Vector v1 = B-A,v2 = P - A;

return fabs(Cross(v1,v2)/Length(v1));
}

double DistanceToSegment(Point P,Point A,Point B) //点到线段的最短距离
{
if(A == B) return Length(P-A);

Vector v1 = B - A,v2 = P-A,v3 = P-B;

if(dbcmp(Dot(v1,v2))<0) return Length(v2);//在A端点的外面

else if(dbcmp(Dot(v1,v3))>0) return Length(v3);//在B端点的外面

else return fabs(Cross(v1,v2)/Length(v1));
}

Point GetLineProjection(Point P,Point A,Point B) //点在线段上的投影的坐标
{
Vector v = B-A;

return A+v*(Dot(v,P-A)/Dot(v,v));
}

bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2) //判断线段规范相交
{
double c1 = Cross(a2-a1,b1-a1),c2 = Cross(a2-a1,b2-a1),c3 = Cross(b2-b1,a1-b1),c4 = Cross(b2-b1,a2-b1);

return dbcmp(c1)*dbcmp(c2)<0&&dbcmp(c3)*dbcmp(c4)<0;
}

bool OnSegment(Point P,Point A,Point B) { return dbcmp(Cross(A-P,B-P)) == 0 && dbcmp(Dot(A-P,B-P)) < 0;} //判断点P是不是在线段AB上

double PolygonArea(Point *p,int n)//求多边形的有向面积
{
double Area = 0;

for(int i = 1;i < n-1; i++) Area += Cross(p[i]-p[0],p[i+1]-p[0]);

return Area/2;
}

Point GetMorley(Point A,Point B,Point C)
{
Vector v1  = C-B;

double a1 = Angle(A-B,v1);

v1 = Rotate(v1,a1/3);

Vector v2 = B-C;

double a2 = Angle(A-C,v2);

v2 = Rotate(v2,-a2/3);

return GetLineIntersection(B,v1,C,v2);
}

int main()
{
Point a[4],b[4];

int T;

scanf("%d",&T);

while(T--)
{
for(int i = 0;i<3;i++)
{
scanf("%lf %lf",&a[i].x,&a[i].y);
}

b[0] = GetMorley(a[0],a[1],a[2]);

b[1] = GetMorley(a[1],a[2],a[0]);

b[2] = GetMorley(a[2],a[0],a[1]);

for(int i = 0; i < 3; i++)
{
if(i)
printf(" ");

printf("%.6f %.6f",b[i].x,b[i].y);
}

printf("\n");
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: