• [笔记-计算几何] 计算几何基础


    [kuangbin带你飞]专题十三 基础计算几何 https://vjudge.net/contest/240243
    [NWPU][2018暑假集训]day12

    模版

    我们直接一点

    #define PI 3.1415926
    #include <cmath>
    #include <cstdio>
    #include <vector>
    #include <algorithm>
    using namespace std;
    const double eps=1e-10;
    const int maxn=5e3+20;
    
    struct Point{
        double x, y;
    
        Point(int x=0, int y=0):x(x), y(y) {}
        // no known conversion for argument 1 from 'Point' to 'Point&'
        Point operator + (Point p){return Point(x+p.x, y+p.y);}
        Point operator - (Point p){return Point(x-p.x, y-p.y);}
        Point operator * (double k){return Point(k*x, k*y);}
        Point operator / (double k){return Point(x/k, y/k);}
        bool operator < (Point p) const{return (x==p.x)?(y<p.y):(x<p.x);}   // need eps?
        bool operator == (const Point p) const{return fabs(x-p.x)<eps&&fabs(y-p.y)<eps;}
        double norm(void){return x*x+y*y;}
        double abs(void){return sqrt(norm());}
        double dot(Point p){return x*p.x+y*p.y;}        // 可计算cos正负
        double cross(Point p){return x*p.y-y*p.x;}      // 可计算sin正负
    };
    struct Segment{Point p1, p2;};
    struct Circle{Point o; double rad;};
    typedef Point Vector;
    typedef vector<Point> Polygon;
    typedef Segment Line;
    
    // 点与向量的关系
    //  1:在向量的左边
    // -1:在向量的右边
    //  2:在向量的反方向
    // -2:在向量的正方向
    //  0:在向量上
    int ccw(Point p0, Point p1, Point p2){
        Vector v1=p1-p0, v2=p2-p0;
        if (v1.cross(v2)>eps) return 1;         // anti-clockwise
        if (v1.cross(v2)<-eps) return -1;       // clockwise
        if (v1.dot(v2)<0) return 2;
        if (v1.norm()<v2.norm()) return -2;
        return 0;
    }
    
    // 求向量投影
    Point project(Segment s, Point p){
        Vector base=s.p2-s.p1;
        double k=(p-s.p1).cross(base)/base.norm();
        return s.p1+base*k;
    }
    
    // 求向量映像
    Point reflect(Segment s, Point p){
        return p+(project(s, p)-p)*2;
    }
    
    // 点到直线间距
    double lineDist(Line l, Point p){
        return abs((l.p2-l.p1).cross(p-l.p1)/(l.p2-l.p1).abs());
    }
    
    // 点到线段间距
    // 在线段左边为点到左端点距离,右边同理
    double SegDist(Segment s, Point p){
        if ((s.p2-s.p1).dot(p-s.p1)<0) return Point(p-s.p1).abs();
        if ((s.p1-s.p2).dot(p-s.p2)<0) return Point(p-s.p2).abs();
        return abs((s.p2-s.p1).cross(p-s.p1)/(s.p2-s.p1).abs());
    }
    
    // 判断两线段相交,若p1, p2为直线,则不需要第2行的判断
    bool intersect(Point p1, Point p2, Point p3, Point p4){
        return ccw(p1, p2, p3)*ccw(p1, p2, p4)<=0 &&
                ccw(p3, p4, p1)*ccw(p3, p4, p2)<=0;
    }
    
    // 求两线段交点
    Point getCrossPoint(Segment s1, Segment s2){
        Vector base=s2.p2-s2.p1;
        double d1=abs(base.cross(s1.p1-s2.p1));
        double d2=abs(base.cross(s1.p2-s2.p1));
        double t=d1/(d1+d2);
        return s1.p1+(s1.p2-s1.p1)*t;
    }
    
    // 求多边形面积
    // 注意各点顺时针或逆时针,非凸亦可求
    double area(Polygon poly){
        double res=0; long long size=poly.size();
        for (int i=0; i<poly.size(); i++)
            res+=poly[i].cross(poly[(i+1)%size]);
        return abs(res/2);
    }
    
    // 判断点在多边形内
    int contain(Polygon poly, Point p){
        int n=poly.size();
        bool flg=false;
        for (int i=0; i<n; i++){
            Point a=poly[i]-p, b=poly[(i+1)%n]-p;
            if (ccw(poly[i], poly[(i+1)%n], p)==0) return 1;    // 1 means on the polygon.
            if (a.y>b.y) swap(a, b);
            if (a.y<0 && b.y>0 && a.cross(b)>0) flg=!flg;
        }return flg?2:0;                                        // 2 fo inner, 0 for outer.
    }
    
    // 求凸包,安德鲁算法 O(nlogn)
    Polygon convexHull(Polygon poly){
        if (poly.size()<3) return poly;
        Polygon upper, lower;
        sort(poly.begin(), poly.end());
        upper.push_back(poly[0]); upper.push_back(poly[1]);
        lower.push_back(poly[poly.size()-1]); lower.push_back(poly[poly.size()-2]);
        for (int i=2; i<poly.size(); i++){
            for (int n=upper.size()-1; n>=1 && ccw(upper[n-1], upper[n], poly[i])!=-1; n--)
                upper.pop_back();
            upper.push_back(poly[i]);
        }
        for (int i=poly.size()-3; i>=0; i--){
            for (int n=lower.size()-1; n>=1 && ccw(lower[n-1], lower[n], poly[i])!=-1; n--)
                lower.pop_back();
            lower.push_back(poly[i]);
        }
        for (int i=1; i<lower.size(); i++)
            upper.push_back(lower[i]);
        return upper;
    }
    
  • 相关阅读:
    GridView合并行代码
    GridView合并行头代码
    Javascript 的几种写法与提示
    [转] 浅谈MSSQL锁机制
    Two ways of using memory: Stack and Heap
    You have to know how .Net code "managed"?
    Sql Server Profiler
    InterProcess Communication
    database Index
    敏捷开发
  • 原文地址:https://www.cnblogs.com/tanglizi/p/9403852.html
Copyright © 2020-2023  润新知