zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    js中Math.random()生成指定范围数值的随机数【转】
    JS绘制生成花瓣效果的方法【转】
    php 解决json_encode中文UNICODE转码问题【转】
    JS/JQuery获取当前元素的上一个/下一个兄弟级元素等元素的方法【转】
    PHP数据类型转换(字符转数字,数字转字符)【转】
    PHP 数组转字符串,与字符串转数组【转】
    js中forEach,for in,for of循环的用法【转】
    layui下的checkbox用js如何选中它【转】
    js数组与字符串的相互转换方法【转】
    JS判断网页是否为手机打开【转】
  • 原文地址:https://www.cnblogs.com/Sunnie69/p/5522929.html
Copyright © 2011-2022 走看看