codeforces 23D Tetragon 计算几何

题意:给你三条相等的边的中点,问是否存在这样的凸四边形

思路:因为答案是四边形,所以这三条边肯定是连续的,我们枚举中间那条边。

不妨设中间的边的两个端点分别为p和q,其中点为b,相邻两边的中点为a和c。

则显然,p必须在线段ab的垂直平分线上,q必须在线段bc的垂直平分线上。

#include <iostream>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define eps 1e-8
struct point
{
    double x,y;
    point()
    {
        x=y=0;
    }
    point(double xx,double yy)
    {
        x=xx;
        y=yy;
    }
} p[3],ans[4],w[4];
int top;
double dist(point a,point b)
{
    return hypot(fabs(a.x-b.x),fabs(a.y-b.y));
}
double Mul(point a,point b,point c)
{
    return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
int cmp(const void *a,const void *b)
{
    point c=*(point *)a;
    point d=*(point *)b;
    double k=Mul(ans[0],c,d);
    if(k<0||(!k&&dist(c,ans[0])>dist(d,ans[0]))) return 1;
    return -1;
}
//凸包模板
void con()
{
    int i;
    int n=4;
    for(i=1;i<n;i++)
    {
        point temp;
        if(ans[i].y<ans[0].y||(ans[i].y==ans[0].y&&ans[i].x<ans[0].x))
        {
            temp=ans[i];
            ans[i]=ans[0];
            ans[0]=temp;
        }
    }
    qsort(ans+1,n-1,sizeof(ans[0]),cmp);
    w[0]=ans[0];
    w[1]=ans[1];
    w[2]=ans[2];
    top=2;
    for(i=3;i<n;i++)
    {
        while(top>=2&&Mul(w[top-1],w[top],ans[i])<=0) top--;
        top++;
        w[top]=ans[i];
    }
}
bool TB()
{
    top=0;
    con();
    int i,j,k;
    if(top==3)
    {
        for(i=0;i<=3;i++)
        {
            for(j=0;j<=3;j++)
            {
                for(k=0;k<=3;k++)
                {
                    if(i==j||i==k||j==k) continue;
                    //三点不在一条直线上
                    if(fabs((w[j].y-w[i].y)*(w[j].x-w[k].x)-(w[j].y-w[k].y)*(w[j].x-w[i].x))<eps) return 0;
                }
            }
        }
        double dis[5];
        for(i=0;i<4;i++)
            dis[i]=dist(w[i],w[(i+1)%4]);
        sort(dis,dis+4);
        int tp1=0,tp2=0;
        for(i=0;i<4;i++)
        {
            if(fabs(dis[i]-dis[0])<eps) tp1++;
            if(fabs(dis[i]-dis[3])<eps) tp2++;
        }
        if(tp1>=3||tp2>=3) return 1;
        return 0;
    }
    return 0;
}
int solve(point b,point a,point c)
{
    double k1,k2;
    point d=point((a.x+b.x)/2,(a.y+b.y)/2);
    point e=point((c.x+b.x)/2,(c.y+b.y)/2);
    if(fabs(a.y-b.y)<eps)
    {
        if(fabs(c.y-b.y)<eps) return 0;
        else
        {
            k2=-(c.x-b.x)/(c.y-b.y);
            double uy=-(k2*(2*b.x-d.x-e.x)+e.y-2*b.y);
            ans[0]=point(d.x,uy);
            ans[1]=point(2*b.x-d.x,2*b.y-uy);
            ans[2]=point(2*c.x-ans[1].x,2*c.y-ans[1].y);
            ans[3]=point(2*a.x-ans[0].x,2*a.y-ans[0].y);
            return TB();
        }
    }
    else
    {
        k1=-(a.x-b.x)/(a.y-b.y);
        if(fabs(c.y-b.y)<eps)
        {
            double ux=2*b.x-e.x;
            ans[0]=point(ux,k1*(ux-d.x)+d.y);
            ans[1]=point(2*b.x-ux,2*b.y-k1*(ux-d.x)-d.y);
            ans[2]=point(2*c.x-ans[1].x,2*c.y-ans[1].y);
            ans[3]=point(2*a.x-ans[0].x,2*a.y-ans[0].y);
            return TB();
        }
        else
        {
            k2=-(c.x-b.x)/(c.y-b.y);
            if(fabs(k1-k2)<eps) return 0;
            double ux=-k1*d.x+2*k2*b.x-k2*e.x+e.y+d.y-2*b.y;
            ux/=(k2-k1);
            ans[0]=point(ux,k1*(ux-d.x)+d.y);
            ans[1]=point(2*b.x-ux,2*b.y-k1*(ux-d.x)-d.y);
            ans[2]=point(2*c.x-ans[1].x,2*c.y-ans[1].y);
            ans[3]=point(2*a.x-ans[0].x,2*a.y-ans[0].y);
            return TB();
        }
    }
}
int main()
{
    int T,i,j,k,m,n,flag;
    point a,b,c;
    scanf("%d",&T);
    while(T--)
    {
        for(i=0; i<3; i++)
            scanf("%lf%lf",&p[i].x,&p[i].y);
        flag=0;
        for(i=0; i<3; i++)
        {
            b=p[i];
            a=p[(i+1)%3];
            c=p[(i+2)%3];
            if(solve(b,a,c))
            {
                flag=1;
                break;
            }
        }
        if(flag)
        {
            printf("YES\n");
            for(i=0; i<4; i++)
                printf("%.10f %.10f ",w[i].x,w[i].y);
            printf("\n");
        }
        else printf("NO\n\n");
    }
    return 0;
}

 

posted on 2016-03-28 14:20  13rj1115  阅读(351)  评论(0编辑  收藏  举报

导航