码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 2826 An Easy Problem? 判断线段相交

时间:2017-07-22 13:27:37      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:return   点积   断线   fabs   print   put   tle   log   第一个   

POJ 2826 An Easy Problem?! -- 思路来自kuangbin博客

下面三种情况比较特殊,特别是第三种

技术分享

G++怎么交都是WA,同样的代码C++A了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

const double eps = 1e-8;
const double PI = acos(-1.0);
const double INF = 1e5;

int sgn(double x)
{
    if(fabs(x) < eps) return 0;
    return x < 0 ? -1:1;
}

struct Point
{
    double x,y;
    Point() {}
    Point(double _x,double _y)
    {
        x = _x,y = _y;
    }
    Point operator -(const Point &b)const
    {
        return Point(x - b.x,y - b.y);
    }
    //叉积
    double operator ^(const Point &b)const
    {
        return x*b.y - y*b.x;
    }
    //点积
    double operator *(const Point &b)const
    {
        return x*b.x + y*b.y;
    }
};

struct Line
{
    Point p,q;
    Line() {};
    Line(Point _p,Point _q)
    {
        p = _p,q = _q;
    }
    //两直线相交求交点
    //第一个值为0表示直线重合,为1表示平行,为2表示相交
    //只有第一个值为2时,交点才有意义
    pair<int,Point> operator &(const Line &b)const
    {
        Point res = p;
        if(sgn((p-q)^(b.p-b.q)) == 0)
        {
            if(sgn((p-b.q)^(b.p-b.q)) == 0)
                return make_pair(0,res);//重合
            else return make_pair(1,res);//平行
        }
        double t = ((p-b.p)^(b.p-b.q))/((p-q)^(b.p-b.q));
        res.x += (q.x-p.x)*t;
        res.y += (q.y-p.y)*t;
        return make_pair(2,res);
    }
};

//*判断线段相交
bool inter(Line l1,Line l2)
{
    return
        max(l1.p.x,l1.q.x) >= min(l2.p.x,l2.q.x) &&
        max(l2.p.x,l2.q.x) >= min(l1.p.x,l1.q.x) &&
        max(l1.p.y,l1.q.y) >= min(l2.p.y,l2.q.y) &&
        max(l2.p.y,l2.q.y) >= min(l1.p.y,l1.q.y) &&
        sgn((l2.p-l1.q)^(l1.p-l1.q))*sgn((l2.q-l1.q)^(l1.p-l1.q)) <= 0 &&
        sgn((l1.p-l2.q)^(l2.p-l2.q))*sgn((l1.q-l2.q)^(l2.p-l2.q)) <= 0;
}

Point pot[105],peg;
double rad;

int main()
{
//    freopen("in.txt","r",stdin);
    int t;
    double x1,y1,x2,y2;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
        Line L1=Line(Point(x1,y1),Point(x2,y2));
        scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
        Line L2=Line(Point(x1,y1),Point(x2,y2));
        if(sgn(L1.p.y - L1.q.y)==0 || sgn(L2.p.y - L2.q.y)==0)
        {
            puts("0.00");
            continue;
        }
        if(!inter(L1,L2))
        {
            puts("0.00");
            continue;
        }
        if(sgn(L1.p.y - L1.q.y) < 0) swap(L1.p,L1.q);
        if(sgn(L2.p.y - L2.q.y) < 0) swap(L2.p,L2.q);
        if(inter(Line(L1.p,Point(L1.p.x,INF)),L2))
        {
            puts("0.00");
            continue;
        }
        if(inter(Line(L2.p,Point(L2.p.x,INF)),L1))
        {
            puts("0.00");
            continue;
        }
        pair<int,Point> pr=L1 & L2;
        Point cp=pr.second;
        pr=Line(L1.p,Point(INF,L1.p.y)) & L2;
        double ans=fabs((L1.p-cp)^(pr.second-cp))/2;
        pr=Line(L2.p,Point(INF,L2.p.y)) & L1;
        ans=min(ans,fabs((L2.p-cp)^(pr.second-cp))/2);
        printf("%.2lf\n",ans);
    }
    return 0;
}

 

POJ 2826 An Easy Problem? 判断线段相交

标签:return   点积   断线   fabs   print   put   tle   log   第一个   

原文地址:http://www.cnblogs.com/pach/p/7220927.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!