hdu Pizza Hub 计算几何

版权声明:本文为博主原创文章,转载请附上原博客链接。 https://blog.csdn.net/Dale_zero/article/details/82185108

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6398

这题做了一天真是恶心!!!计算几何的题目都是这样。。。

计算几何需要注意的最大的问题就是角度或者sin、cos的值的大小判断是一个模糊的界限,不管哪一个比较大,只要差值不超过

规定的eps(一般是1e-6)就可以视为是相等的。不能单纯地用大于号或者小于号判断。

如a>b,但是fabs(a-b)<eps,则此时a=b。

这道题分为两种情况

①三角形的一条边与矩形底边重合

②三角形一个顶点卡在矩形角上,另一个搭在对面的一条边上。

一共是3+6*2=15种情况,计算最小值即可,只是debug太恶心了

注释就不删了,留着以后自己可能会看。

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define mod 1000000007
#define For(i,m,n) for(int i=m;i<=n;i++)
#define Dor(i,m,n) for(int i=m;i>=n;i--)
#define LL long long
#define lan(a,b) memset(a,b,sizeof(a))
#define sqr(a) a*a
using namespace std;

const int maxn=303;
const double pi=atan(1.0)*4;
const double len=1.0001*1.0001;
//基础点和向量运算
struct Point{
    double x,y;
    Point(double x=0,double y=0):x(x),y(y){}
};
typedef Point Vector;
Vector operator + (Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}
Vector operator - (Vector A,Vector B){return Vector(A.x-B.x,A.y-B.y);}
Vector operator * (Vector A,double p){return Vector(A.x*p,A.y*p);}
Vector operator / (Vector A,double p){return Vector(A.x/p,A.y/p);}
bool operator <(const Point& a, const Point& b)
{
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
const double eps=1e-6;
int dcmp(double x)//判断正负,或者等于0
{
    if(fabs(x)<eps)return 0;else return x<0?-1:1;
}
bool operator==(const Point& a,const Point &b)
{
    return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}
double Dot(Vector A, Vector B){return A.x*B.x+A.y*B.y;}//点积
double Length(Vector A){return sqrt(Dot(A,A));}//OA长
double Angle(Vector A,Vector B){return acos(Dot(A,B)/Length(A)/Length(B));}//OA和OB的夹角
double Cross(Vector A,Vector B){return A.x*B.y-A.y*B.x;}//叉积
double Area2(Point A,Point B,Point C){return Cross(B-A,C-A);}//三角形面积
Vector Rotate(Vector A,double rad)//rad为弧度,旋转rad度
{
    return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
Vector Normal(Vector A)//A的单位法向量,A不能为零向量
{
    double L=Length(A);
    return Vector(-A.y/L,A.x/L);
}

int main()
{
//    freopen("b.in","r",stdin);
//
//    freopen("2.txt","w",stdout);
    int t;
    scanf("%d",&t);
    while(t--)
    {
        double x1,y1,x2,y2,x3,y3,w;
        scanf("%lf%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3,&w);
        Point a=Point(x1,y1);
        Point b=Point(x2,y2);
        Point c=Point(x3,y3);
        double s=Area2(a,b,c);
        double minn=inf;

        ///①:其中一条边与矩形底边重合
        if(Length(a-b)<=w)
        {
            double tem=fabs(Length(c-a)*cos(Angle(b-a,c-a)));
            double tem1=fabs(Length(c-b)*cos(Angle(a-b,c-b)));
//            printf("a,b tem1=%lf tem2=%lf\n",tem,tem1);
            if(tem1<=w&&tem<=w)
                minn=min(minn,Length(c-a)*sin(Angle(b-a,c-a)));
//            printf("%lf %lf\n",cos(Angle(b-a,c-a)),(sqr(Length(b-a))+sqr(Length(c-a))-sqr(Length(b-c)))/(2*Length(b-a)*Length(c-a)));
//            printf("%lf\n",Area2(a,b,c)*2/Length(b-a));
        }
        if(Length(c-b)<=w)
        {
             double tem=fabs(Length(a-c)*cos(Angle(b-c,a-c)));
            double tem1=fabs(Length(a-b)*cos(Angle(c-b,a-b)));
//            printf("b,c tem1=%lf tem2=%lf\n",tem,tem1);
            if(tem1<=w&&tem<=w)
                minn=min(minn,Length(a-c)*sin(Angle(b-c,a-c)));
        }
        if(Length(a-c)<=w)
        {
             double tem=fabs(Length(b-a)*cos(Angle(b-a,c-a)));
            double tem1=fabs(Length(b-c)*cos(Angle(b-c,a-c)));
//            printf("a,c tem1=%lf tem2=%lf\n",tem,tem1);
            if(tem1<=w&&tem<=w)
                minn=min(minn,Length(b-a)*sin(Angle(b-a,c-a)));
        }
//        printf("minn=%lf\n",minn);
        ///②:两点卡在矩形边上

        double len,a1,b1,c1;

        ///顶点为a,b在边上
        len=Length(a-b);
        if(len>w)
        {
            a1=acos(w/len);
            b1=Angle(c-a,b-a);
            if(b1<a1)
            {
                 c1=a1-b1;
                 double tem=w/cos(c1);
                 if(tem>Length(c-a))
                    minn=min(minn,tan(a1)*w);
            }
//printf("a,b minn=%lf\n",minn);
            if(a1+b1<pi/2||fabs(pi/2-a1-b1)<eps)
            {
                double tem=w/cos(a1+b1);
                if(tem>Length(c-a)||fabs(pi/2-a1-b1)<eps)
                {
                    minn=min(minn,max(Length(c-a)*sin(a1+b1),tan(a1)*w));
//                    minn=min(minn,tan(a1)*w);
                }
            }
        }


//printf("a,b minn=%lf\n",minn);

        ///顶点为a,c在边上
        len=Length(a-c);

        if(len>w)
        {
            a1=acos(w/len);
            b1=Angle(c-a,b-a);
//            printf("a1=%lf b1=%lf\n",a1,cos(b1));
            if(b1<a1)
            {
                 c1=a1-b1;
                 double tem=w/cos(c1);
                 if(tem>Length(b-a))
                    minn=min(minn,tan(a1)*w);
            }
            if(a1+b1<pi/2||fabs(pi/2-a1-b1)<eps)
            {
                double tem=w/cos(a1+b1);
                if(tem>Length(b-a)||fabs(pi/2-a1-b1)<eps)
                {
                    minn=min(minn,max(Length(b-a)*sin(a1+b1),tan(a1)*w));

                }
            }
        }

//printf("a,c minn=%lf\n",minn);

        ///顶点为b,a在边上
        len=Length(b-a);

        if(len>w)
        {
            a1=acos(w/len);
            b1=Angle(a-b,c-b);
//            printf("a1=%lf b1=%lf %.20lf %.20lf\n",a1,b1,a1+b1,fabs(pi/2-a1-b1));
            if(b1<a1)
            {
                 c1=a1-b1;
                 double tem=w/cos(c1);
                 if(tem>Length(c-b))
                    minn=min(minn,tan(a1)*w);
            }
            if(a1+b1<pi/2||fabs(pi/2-a1-b1)<eps)
            {
                double tem=w/cos(a1+b1);
//                printf("ok\n");
//                if(fabs(pi/2-a1-b1)<eps)
//                    minn=min(minn,max(Length(c-b)*sin(a1+b1),tan(a1)*w));
                if(tem>Length(c-b)||fabs(pi/2-a1-b1)<eps)
                {
//                    printf("%lf %lf\n",Length(c-b)*sin(a1+b1),tan(a1)*w);
                    minn=min(minn,max(Length(c-b)*sin(a1+b1),tan(a1)*w));
                }
            }
        }

//printf("b,a minn=%lf\n",minn);

        ///顶点为b,c在边上
        len=Length(b-c);

        if(len>w)
        {
            a1=acos(w/len);
            b1=Angle(a-b,c-b);
//            printf("a1=%lf b1=%lf\n",a1,b1);
            if(b1<a1)
            {
                 c1=a1-b1;
                 double tem=w/cos(c1);
                 if(tem>Length(a-b))
                    minn=min(minn,tan(a1)*w);
            }
            if(a1+b1<pi/2||fabs(pi/2-a1-b1)<eps)
            {
                double tem=w/cos(a1+b1);
                if(tem>Length(a-b)||fabs(pi/2-a1-b1)<eps)
                {
                    minn=min(minn,max(Length(a-b)*sin(a1+b1),tan(a1)*w));

                }
            }
        }


//printf("b,c minn=%lf\n",minn);

        ///顶点为c,a在边上
        len=Length(a-c);

        if(len>w)
        {
            a1=acos(w/len);
            b1=Angle(a-c,b-c);
//            printf("a1=%lf b1=%lf\n",a1,b1);
            if(b1<a1)
            {
                 c1=a1-b1;
//                 printf("c1=%lf\n",c1);
                 double tem=w/cos(c1);
//                 printf("tem=%lf\n len(b-c)=%lf\n",tem,Length(b-c));
                 if(tem>Length(b-c))
                    minn=min(minn,tan(a1)*w);//printf("1 min:%lf\n",tan(a1)*w);
            }
            if(a1+b1<pi/2||fabs(pi/2-a1-b1)<eps)
            {
                double tem=w/cos(a1+b1);
                if(tem>Length(b-c)||fabs(pi/2-a1-b1)<eps)
                {
                    minn=min(minn,max(Length(b-c)*sin(a1+b1),tan(a1)*w));//printf("2 min:%lf\n",Length(b-c)*sin(a1+b1));
                }
            }
        }

//printf("c,a minn=%lf\n",minn);

        ///顶点为c,b在边上
        len=Length(b-c);

        if(len>w)
        {
            a1=acos(w/len);
            b1=Angle(a-c,b-c);
//            printf("a1=%lf b1=%lf\n",a1,b1);
            if(b1<a1)
            {
                 c1=a1-b1;
                 double tem=w/cos(c1);
                 if(tem>Length(a-c))
                    minn=min(minn,tan(a1)*w);//printf("1 min:%lf\n",tan(a1)*w);
            }
            if(a1+b1<pi/2||fabs(pi/2-a1-b1)<eps)
            {
                double tem=w/cos(a1+b1);
                if(tem>Length(a-c)||fabs(pi/2-a1-b1)<eps)
                {
                    minn=min(minn,max(Length(a-c)*sin(a1+b1),tan(a1)*w));//printf("2 min:%lf\n",Length(a-c)*sin(a1+b1));;
                }
            }
        }


//printf("c,b minn=%lf\n",minn);
        if(minn!=inf)
            printf("%.9lf\n",minn);
        else
            printf("impossible\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Dale_zero/article/details/82185108
今日推荐