• 计算几何基本函数


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std ;
    const double eps = 1e-8;
    const double PI = acos(-1.0);
    int sgn(double x)
    {
        if(fabs(x) < eps)return 0;
        if(x < 0)return -1;
        else return 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;
        }
        //绕原点旋转角度B(弧度值),后x,y的变化
        void transXY(double B)
        {
            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);
        }
    };
    //*两点间距离
    double dist(Point a,Point b)
    {
        return sqrt((a-b)*(a-b));
    }
    //*判断三点共线 
    bool online(Point p1, Point p2, Point p3)
    {
        return 
            sgn(p3.x-min(p1.x,p2.x)) >= 0 && 
            sgn(p3.x-max(p1.x,p2.x)) <= 0 &&
            sgn(p3.y-min(p1.y,p2.y)) >= 0 && 
            sgn(p3.y-max(p1.y,p2.y)) <= 0;
    }
    //*判断线段相交
    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;
    }
    //判断直线和线段相交
    bool Seg_inter_line(Line l1,Line l2) //判断直线l1和线段l2是否相交
    {
        return sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e)) <= 0;
    }
    //点到直线距离
    //返回为result,是点到直线最近的点
    Point PointToLine(Point P,Line L)
    {
        Point result;
        double t = ((P-L.s)*(L.e-L.s))/((L.e-L.s)*(L.e-L.s));
        result.x = L.s.x + (L.e.x-L.s.x)*t;
        result.y = L.s.y + (L.e.y-L.s.y)*t;
        return result;
    }
    //点到线段的距离
    //返回点到线段最近的点
    Point NearestPointToLineSeg(Point P,Line L)
    {
        Point result;
        double t = ((P-L.s)*(L.e-L.s))/((L.e-L.s)*(L.e-L.s));
        if(t >= 0 && t <= 1)
        {
            result.x = L.s.x + (L.e.x - L.s.x)*t;
            result.y = L.s.y + (L.e.y - L.s.y)*t;
        }
        else
        {
            if(dist(P,L.s) < dist(P,L.e))
                result = L.s;
            else result = L.e;
        }
        return result;
    }
    //计算多边形面积
    //点的编号从0~n-1
    double CalcArea(Point p[],int n)
    {
        double res = 0;
        for(int i = 0;i < n;i++)
            res += (p[i]^p[(i+1)%n])/2;
        return fabs(res);
    }
    //*判断点在线段上
    bool OnSeg(Point P,Line L)
    {
        return
            sgn((L.s-P)^(L.e-P)) == 0 &&
            sgn((P.x - L.s.x) * (P.x - L.e.x)) <= 0 &&
            sgn((P.y - L.s.y) * (P.y - L.e.y)) <= 0;
    }
    //*判断点在凸多边形内
    //点形成一个凸包,而且按逆时针排序(如果是顺时针把里面的<0改为>0)
    //点的编号:0~n-1
    //返回值:
    //-1:点在凸多边形外
    //0:点在凸多边形边界上
    //1:点在凸多边形内
    int inConvexPoly(Point a,Point p[],int n)
    {
        for(int i = 0;i < n;i++)
        {
            if(sgn((p[i]-a)^(p[(i+1)%n]-a)) < 0)return -1;
            else if(OnSeg(a,Line(p[i],p[(i+1)%n])))return 0;
        }
        return 1;
    }
    //*判断点在任意多边形内
    //射线法,poly[]的顶点数要大于等于3,点的编号0~n-1
    //返回值
    //-1:点在凸多边形外
    //0:点在凸多边形边界上
    //1:点在凸多边形内
    int inPoly(Point p,Point poly[],int n)
    {
        int cnt;
        Line ray,side;
        cnt = 0;
        ray.s = p;
        ray.e.y = p.y;
        ray.e.x = -100000000000.0;//-INF,注意取值防止越界
        for(int i = 0;i < n;i++)
        {
            side.s = poly[i];
            side.e = poly[(i+1)%n];
            if(OnSeg(p,side))return 0;
            //如果平行轴则不考虑
            if(sgn(side.s.y - side.e.y) == 0)
                continue;
            if(OnSeg(side.s,ray))
            {
                if(sgn(side.s.y - side.e.y) > 0)cnt++;
            }
            else if(OnSeg(side.e,ray))
            {
                if(sgn(side.e.y - side.s.y) > 0)cnt++;
            }
            else if(inter(ray,side))
                cnt++;
        }
        if(cnt % 2 == 1)return 1;
        else return -1;
    }
    //判断凸多边形
    //允许共线边
    //点可以是顺时针给出也可以是逆时针给出
    //点的编号0~n-1
    bool isconvex(Point poly[],int n)
    {
        bool s[3];
        memset(s,false,sizeof(s));
        for(int i = 0;i < n;i++)
        {
            s[sgn( (poly[(i+1)%n]-poly[i])^(poly[(i+2)%n]-poly[i]) )+1] = true;
            if(s[0] && s[2])return false;
        }
        return true;
    }
    //过三点求圆心坐标
    Point waixin(Point a,Point b,Point c)
    {
        double a1 = b.x - a.x, b1 = b.y - a.y, c1 = (a1*a1 + b1*b1)/2;
        double a2 = c.x - a.x, b2 = c.y - a.y, c2 = (a2*a2 + b2*b2)/2;
        double d = a1*b2 - a2*b1;
        return Point(a.x + (c1*b2 - c2*b1)/d, a.y + (a1*c2 -a2*c1)/d);
    }
    int main()
    {
        
        return 0 ;
    }
    View Code
  • 相关阅读:
    48. Rotate Image
    47. Permutations II
    46. Permutations
    45. Jump Game II
    44. Wildcard Matching
    43. Multiply Strings
    42. Trapping Rain Water
    Python_匿名函数
    Python_内置函数之map()
    Python_面向对象_单例模式
  • 原文地址:https://www.cnblogs.com/xiaohongmao/p/3784493.html
Copyright © 2020-2023  润新知