zoukankan      html  css  js  c++  java
  • 计算几何板子(持续更新)

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    typedef double db;
    const db Pi = acos(-1);
    const db inf = 1e15; 
    const db eps = 1e-11;
    
    // 判断正、负还是0
    inline int dcmp(db x){
        if(fabs(x) < eps)  return 0;
        return x > 0 ? 1 : -1; 
    }
    
    db Acos(db x){
    	if(x <= -1)	 return Pi;
    	if(x >= 1)	 return 0;
    	return acos(x);
    }
    
    db Asin(db x){
    	if(x >= 1)  return Pi / 2;
    	if(x <= -1)  return -Pi / 2;
    	return asin(x); 	
    }
    
    db Tan(db x){
        if(dcmp(x - Pi / 2) == 0)  return 4e18;
        return tan(x);
    }
    
    typedef struct Point{
        db x, y;
        Point(db a = 0, db b = 0) { x = a, y = b; }
        Point operator -(const Point &ret)const { return Point{x - ret.x, y - ret.y}; }
        Point operator +(const Point &ret)const { return Point{x + ret.x, y + ret.y}; }
        Point operator *(db mul)const { return Point{x * mul, y * mul}; }
        Point operator /(db div)const { return Point{x / div, y / div}; }
        //db operator *(const Point &ret) { return x * ret.x + y * ret.y; }  // 点积
        //db operator ^(const Point &ret) { return x * ret.y - y * ret.x; }  // 叉积
        db length() { return sqrt(x * x + y * y); }
    }Vector;
    
    struct Line{
        Point p[2];
        db k, b;
        Line(db a = 0, db b = 0, db c = 0, db d = 0) { p[0].x = a, p[0].y = b, p[1].x = c, p[1].y = d; }
        Line(Point a, Point b) { p[0] = a, p[1] = b; }
    
        db length(){
            return sqrt((p[0].x - p[1].x) * (p[0].x - p[1].x) + (p[0].y - p[1].y) * (p[0].y - p[1].y));
        }
    
        // 获取直线k,b参数
        void get_para(){
            if(dcmp(p[0].x - p[1].x) == 0){
                k = inf;
                b = inf;
            }
            else{
                k = (p[1].y - p[0].y) / (p[1].x - p[0].x);
                b = p[0].y - k * p[0].x;
            }
        }
    
        // 点到直线距离
        db dis_Point(Point ret){
            db x = ret.x,  y = ret.y;
            if(k == inf)  return fabs(x - p[0].x);
            return fabs(k * x - y + b) / sqrt(1 + k * k);
        }
    };
    
    // 点积
    db dot(Vector a, Vector b) { return a.x * b.x + a.y * b.y; }
    // 叉积
    db cross(Vector a, Vector b) { return a.x * b.y - a.y * b.x; }
    
    // 判断两直线是否相交,包含端点
    bool intersection(const Line &l1, const Line &l2){
        //  快速排斥实验
        if(max(l1.p[0].x, l1.p[1].x) < min(l2.p[0].x, l2.p[1].x) || max(l2.p[0].x, l2.p[1].x) < min(l1.p[0].x, l1.p[1].x))  return false;
        if(max(l1.p[0].y, l1.p[1].y) < min(l2.p[0].y, l2.p[1].y) || max(l2.p[0].y, l2.p[1].y) < min(l1.p[0].y, l1.p[1].y))  return false;
        //  跨立实验
        Vector L1 = {l1.p[1].x - l1.p[0].x, l1.p[1].y - l1.p[0].y},  L2 = {l2.p[1].x - l2.p[0].x, l2.p[1].y - l2.p[0].y};
        Vector h = {l2.p[0].x - l1.p[0].x, l2.p[0].y - l1.p[0].y},  hh = {l2.p[1].x - l1.p[0].x, l2.p[1].y - l1.p[0].y};
        if(dcmp(cross(L1, h) * cross(L1, hh)) > 0)  return false;
        h = {l1.p[0].x - l2.p[0].x, l1.p[0].y - l2.p[0].y},  hh = {l1.p[1].x - l2.p[0].x, l1.p[1].y - l2.p[0].y};
        if(dcmp(cross(L2, h) * cross(L2, hh)) > 0)  return false;
        return true;
    }
    
    // 逆时针旋转,顺时针的话角度取反即可
    Point rorate_point(const Point &p, db A){
        return Point{p.x * cos(A) - p.y * sin(A), p.x * sin(A) + p.y * cos(A)};
    }
    
    // 找直线交点
    bool inter_point(const Line &l1, const Line &l2, Point &ans){	
    	Point a = l1.p[0], b = l2.p[0];
        if(l1.k == l2.k)  return 0;
        if(l1.k == inf)  ans = {a.x, l2.k * a.x + l2.b};
        else if(l2.k == inf)  ans = {b.x, l1.k * b.x + l1.b};
        else{
            ans.x = (l1.b - l2.b) / (l2.k - l1.k);
            ans.y = l1.k * ans.x + l1.b;
        }
        return 1;
    }
    
    // 两点距离
    db point_dis(const Point &a, const Point &b){
        return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
    }
    
    // 极角排序  p0是基准点
    Point p0;
    bool cmp_jijiao(Point p1, Point p2){
        Vector a = p1 - p0,  b = p2 - p0;
        return dcmp(cross(a, b)) > 0;
    }
    
    // 凸包,返回凸包周长,n是点的个数
    db Graham(int n){
        // goal是构成凸包的点,n是点的个数, 基准点是1
        Point p[100], goal[100];
        int cnt = 1;
        for(int i = 2; i <= n; ++i){
            if(p[i].y < p[1].y)  swap(p[1], p[i]);
        }
        sort(p + 2, p + 1 + n, cmp_jijiao);
        goal[1] = p[1];
        for(int i = 2; i <= n; ++i){
            while(cnt > 1 && dcmp(cross(goal[cnt] - goal[cnt - 1], p[i] - goal[cnt])) < 0)  --cnt;
            goal[++cnt] = p[i];
        }
        goal[++cnt] = p[1];
        db len = 0;
        for(int i = 2; i <= cnt; ++i)
            len += point_dis(goal[i], goal[i - 1]);
        return len;
    }
    
    // 任意多边形面积,顶点按照顺时针或逆时针排序,n是顶点数
    db GetPolygonArea(int n){
        Point p[100];
        if(n < 3)  return 0;
        db ans = 0;
        for(int i = 2; i < n; ++i)  ans += cross(p[i] - p[1], p[i + 1] - p[1]);
        return fabs(ans / 2);
    }
    
    你只有十分努力,才能看上去毫不费力。
  • 相关阅读:
    PAT 甲级 1115 Counting Nodes in a BST (30 分)
    PAT 甲级 1114 Family Property (25 分)
    PAT 甲级 1114 Family Property (25 分)
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
    Python Ethical Hacking
  • 原文地址:https://www.cnblogs.com/214txdy/p/14157756.html
Copyright © 2011-2022 走看看