D. Tetragon

D. Tetragon
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You're given the centers of three equal sides of a strictly convex tetragon. Your task is to restore the initial tetragon.

Input

The first input line contains one number T — amount of tests (1 ≤ T ≤ 5·104). Each of the following T lines contains numbers x1, y1, x2, y2, x3, y3 — coordinates of different points that are the centers of three equal sides (non-negative integer numbers, not exceeding 10).

Output

For each test output two lines. If the required tetragon exists, output in the first line YES, in the second line — four pairs of numbers — coordinates of the polygon's vertices in clockwise or counter-clockwise order. Don't forget, please, that the tetragon should be strictly convex, i.e. no 3 of its points lie on one line. Output numbers with 9 characters after a decimal point.

If the required tetragon doen't exist, output NO in the first line, and leave the second line empty.

Sample test(s)
Input
3
1 1 2 2 3 3
0 1 1 0 2 2
9 3 7 9 9 8
Output
NO

YES
3.5 1.5 0.5 2.5 -0.5 -0.5 2.5 0.5
NO


解釋:

設ABCD所尋求四邊形K,LM是相等的邊AB,BC和CD,相應的中間,M'對稱相對於L然後BM'= CM = CL = BL = BK,我到M E。 B是三角形的KLM'外心

瞭解B,我們可以得到整個四合院使用的對稱性點,K,L和M然後檢查它是否滿足所有的條件
需要注意的是,我們不知道哪一個給定的點是L,所以我們需要檢查所有的3案件

代碼:

#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <utility>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstdio>

using namespace std;

#define REP(i,n) for((i)=0;(i)<(int)(n);(i)++)
#define foreach(c,itr) for(__typeof((c).begin()) itr=(c).begin();itr!=(c).end();itr++)

struct point
{
    double x,y;
};

#define eps 1.0E-9
#define _abs(x) ((x)>0?(x):-(x))

double area(point P, point Q, point R)
{
    return ((Q.x - P.x) * (R.y - P.y) - (Q.y - P.y) * (R.x - P.x)) / 2.0;
}

point cross(point A, point B, point C, point D)  // AB - CD
{
    double a = -A.y + B.y, b = A.x - B.x, c = A.x * B.y - A.y * B.x, d = -C.y + D.y, e = C.x - D.x, f = C.x * D.y - C.y * D.x;
    point ans = {(c*e - b*f) / (a*e - b*d), (c*d - a*f) / (b*d - a*e)};
    return ans;
}

point func4(point &P, point &M)
{
    point ans = {M.x * 2 - P.x, M.y * 2 - P.y};
    return ans;
}

point func3(point &A, point &B)
{
    double dx = B.x - A.x, dy = B.y - A.y;
    point ans = {A.x + dx / 2.0 - dy / 2.0, A.y + dy / 2.0 + dx / 2.0};
    return ans;
}

vector <point> func2(point A, point B, point C)
{
    point D,E,F,G;

    point H = func3(A,B), I = func3(B,A);
    double dx = B.x - A.x, dy = B.y - A.y;
    H.x += dx;
    H.y += dy;
    I.x += dx;
    I.y += dy;
    point J = func3(B,C), K = func3(C,B);
    E = cross(H,I,J,K);
    D = func4(E,C);
    F = func4(E,B);
    G = func4(F,A);

    vector <point> ans;
    double tmp;
    bool pos = false, neg = false;
    tmp = area(D,E,F);
    if(tmp > -eps) pos = true;
    if(tmp < eps) neg = true;
    tmp = area(E,F,G);
    if(tmp > -eps) pos = true;
    if(tmp < eps) neg = true;
    tmp = area(F,G,D);
    if(tmp > -eps) pos = true;
    if(tmp < eps) neg = true;
    tmp = area(G,D,E);
    if(tmp > -eps) pos = true;
    if(tmp < eps) neg = true;
    if(pos && neg) return ans;
    ans.push_back(D);
    ans.push_back(E);
    ans.push_back(F);
    ans.push_back(G);
    return ans;
}

vector <point> func(point A, point B, point C)
{
    vector <point> ans;
    if(_abs(area(A,B,C)) < eps) return ans;
    ans = func2(A,B,C);
    if(!ans.empty()) return ans;
    ans = func2(B,C,A);
    if(!ans.empty()) return ans;
    ans = func2(C,A,B);
    if(!ans.empty()) return ans;
    return ans;
}

int main(void)
{
    int T,t,i;
    point A,B,C;

    scanf("%d",&T);
    REP(t,T)
    {
        scanf("%lf%lf%lf%lf%lf%lf",&A.x,&A.y,&B.x,&B.y,&C.x,&C.y);
        vector <point> ans = func(A,B,C);
        if(!ans.empty()) printf("YES\n");
        else printf("NO\n");
        REP(i,ans.size())
        {
            printf("%.9f %.9f",ans[i].x,ans[i].y);
            if(i != ans.size() - 1) printf(" ");
        }
        printf("\n");
    }

    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章