zoukankan      html  css  js  c++  java
  • 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
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    Git-更新数据
    iOS开发-基本的网络知识
    iOS开发-单例模式
    iOS开发-多线程知识
    iOS开发-核心动画随笔
    iOS开发-关于网络状态的判断
    毕业设计--天气预报App
    iOS开发-UIColor转UIIamge方法
    iOS开发-用预处理指令代替注释
    JMS 消息服务
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3508764.html
Copyright © 2011-2022 走看看