【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
题意:三角形每个内角的三等分线相交的三角形为等边三角形,求交点坐标。
分析:向量旋转和直线的相交。
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; }
相关文章推荐
- 三次卷积插值
- Ext.js多文件选择上传,
- TortoiseSVN异常:在工作拷贝执行update时,报错--CleanUp
- VC7 HTML Dialog开发实例讲解
- 苹果企业账号打包发布APP流程详解
- Linux netstat --检验本机各端口的网络连接情况
- Linux nc --网络工具
- 虚拟机Ubuntu Server(宿主Win7)更新软件源
- OpenCV杂记01
- Django开发 hello world
- JAVA中String.split()解析字符串的一点细节
- iOS学习笔记(十七)——文件操作(NSFileManager)
- Linux nano --比vim简单的文本编译器
- C++第二次实验
- c++构造函数
- SQL limit offset
- 第一个驱动之helloworld
- C# List Remove 注意事项
- Linux mv --文件或目录改名,移动位置
- Linux mount --挂载文件系统