hdu_1086 You can Solve a Geometry Problem too(计算几何)

http://acm.hdu.edu.cn/showproblem.php?pid=1086


分析:简单计算几何题,相交判断直接用模板即可。

           思路:将第k条直线与前面k-1条直线进行相交判断,因为题目中不排除多条直线相交于同一个点的重复情况。


代码:

 

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>
#include <set>
#include <string>
#include <math.h>
using namespace std;
const double eps = 1e-8;
const double PI = acos(-1.0);  //比直接写3.1415926精确

int sgn(double x)              //三态函数,精确度提高
{
        if(fabs(x) < eps)return 0;
        else 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;
        }
        void transXY(double B)            //绕原点旋转角度B(弧度值),后x,y的变化
        {
                double tx = x,ty = y;        //
                x = tx*cos(B) - ty*sin(B);
                y = tx*sin(B) + ty*cos(B);
        }
};
struct Line
{
        Point s,e;
        Line(){}
        Line(Point _s,Point _e)
        {
                s = _s;e = _e;
        }
        //两直线相交求交点
        //第一个值为0表示直线重合,为1表示平行,为0表示相交,为2是相交
        //只有第一个值为2时,交点才有意义
    pair<int,Point> operator &(const Line &b)const
    {
        Point res = s;
        if(sgn((s-e)^(b.s-b.e)) == 0)
        {
            if(sgn((s-b.e)^(b.s-b.e)) == 0)
                return make_pair(0,res);//重合
            else return make_pair(1,res);//平行
        }
        double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
        res.x += (e.x-s.x)*t;
        res.y += (e.y-s.y)*t;
        return make_pair(2,res);
    }
};
Point ms,me;
Line  ml[120];

//*两点间距离
double dist(Point a,Point b)
{
    return sqrt((a-b)*(a-b));
}
//*判断线段相交
bool inter(Line l1,Line l2)
{
    return
    max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) &&
    max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) &&
    max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) &&
    max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) &&
    sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e)) <= 0 &&
    sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e)) <= 0;
}

int main()
{
    int n;
    int ans;
    while(scanf("%d",&n),n){
        ans=0;
        for(int i=0;i<n;i++){
            scanf("%lf%lf%lf%lf",&ms.x,&ms.y,&me.x,&me.y);
            ml[i].s=ms; ml[i].e=me;
        }
        for(int i=1;i<n;i++)
        for(int j=0;j<i;j++){
            if(inter(ml[i],ml[j])) ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}


 

 

 

转载于:https://www.cnblogs.com/fuhaots2009/p/3508764.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值