• UVA_11178_Morley's_Theorem_(计算几何基础)


    描述


    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=23&page=show_problem&problem=2119

    Morley定理:作三角形ABC每个内角的三等分线,相交形成三角形DEF,则三角形DEF是等边三角形.

    给出三角形的三个顶点ABC的坐标,求出DEF的坐标.

    11178 - Morley's Theorem

    Time limit: 3.000 seconds

    Morleys theorem states that that the lines
    trisecting the angles of an arbitrary plane

    triangle meet at the vertices of an equi-
    lateral 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 gen-
    eralizations, in particular if all of the tri-
    sectors 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 inter-
    sected 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 X A , Y A , X B , Y B , X C , Y C . This six
    integers actually indicates that the Cartesian coordinates of point A, B and C are (X A , Y A ),(X B , Y B )
    and (X C , Y C ) respectively. You can assume that the area of triangle ABC is not equal to zero, 0 ≤
    X A , Y A , X B , Y B , X C , Y C ≤ 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 X D , Y D , X E , Y E , X F , Y F separated by a single space. These six floating-point actually means
    that the Cartesian coordinates of D, E and F are (X D , Y D ),(X E , Y E ) ,(X F , Y F ) 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

    分析


    DEF三个点的求法是一样的,来看D:

    将向量BC逆时针旋转(角ABC)/3,将向量CB顺时针旋转(角ACB)/3,分别得到了直线BD和直线CD的方向向量,再加上点B,C,可以写出直线BD和直线CD(参数方程),然后求两直线的交点即可.

    注意:

    1.get函数中的后两个参数不可颠倒,因为一边是逆时针转,另一边是顺时针转.

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 const double eps=1e-8;
     5 struct Point{
     6     double x,y;
     7     Point(double x=0,double y=0):x(x),y(y){}
     8 };
     9 typedef Point Vector;
    10 
    11 Vector operator + (Point a,Point b){ return Vector(a.x+b.x,a.y+b.y); }
    12 Vector operator - (Point a,Point b){ return Vector(a.x-b.x,a.y-b.y); }
    13 Vector operator * (Point a,double p){ return Vector(a.x*p,a.y*p); }
    14 double dot(Vector a,Vector b){ return a.x*b.x+a.y*b.y; }//点积
    15 double cross(Vector a,Vector b){ return a.x*b.y-a.y*b.x; }//叉积
    16 double length(Vector a){ return sqrt(dot(a,a)); }//向量的模
    17 double angle(Vector a,Vector b){ return acos(dot(a,b)/length(a)/length(b)); }//两向量夹角
    18 Vector rotate(Vector a,double rad){ return Vector(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad)); }//将向量a逆时针旋转rad(弧度制)
    19 Point get_line_intersection(Point P,Vector v,Point Q,Vector w){//求两直线交点(参数方程)
    20     Vector u=P-Q;
    21     double t=cross(w,u)/cross(v,w);
    22     return P+v*t;
    23 }
    24 Point get(Point A,Point B,Point C){//分别算DEF三个点的函数
    25     Vector v1=C-B;
    26     double a1=angle(A-B,v1);
    27     v1=rotate(v1,a1/3);
    28     Vector v2=B-C;
    29     double a2=angle(A-C,v2);
    30     v2=rotate(v2,-a2/3);
    31     return get_line_intersection(B,v1,C,v2);
    32 }
    33 int main(){
    34     int n;
    35     Point A,B,C,D,E,F;
    36     scanf("%d",&n);
    37     while(n--){
    38         scanf("%lf%lf%lf%lf%lf%lf",&A.x,&A.y,&B.x,&B.y,&C.x,&C.y);
    39         D=get(A,B,C);//这里B,C不能写反,因为一个是逆时针转,另一个时顺时针转
    40         E=get(B,C,A);
    41         F=get(C,A,B);
    42         printf("%.6lf %.6lf %.6lf %.6lf %.6lf %.6lf
    ",D.x,D.y,E.x,E.y,F.x,F.y);
    43     }
    44     return 0;
    45 }
    View Code
  • 相关阅读:
    数值的格式化
    最近开发的一个多功能选择器
    OCI22053: 溢出错误的原因和解决方法
    js的四舍五入问题
    Vista 下先安装 VS 再装 IIS 7 运行出现 500.19 Error 的解决方法
    最近开发的一个多功能选择器2
    Oracle REF Cursor 用法(转帖)
    Oracle 查询历史数据(转帖)
    HDU 1203 I NEED A OFFER! 动态规划(01背包)
    HDU 1160 FatMouse's Speed 动态规划
  • 原文地址:https://www.cnblogs.com/Sunnie69/p/5522929.html
Copyright © 2020-2023  润新知