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);
    }
    
    你只有十分努力,才能看上去毫不费力。
  • 相关阅读:
    ORA-12514, TNS:listener does not currently know of service requested in connect descriptor
    Cannot open url. please check this url is correct
    Execution default of goal org.springframework.boot:spring-boot-maven-plugin:1.5.6.RELEASE:repackage failed: Unable to find main class
    eclipse点击空白处自动打开项目
    Caused by: org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 2
    git忽略文件
    org.elasticsearch.transport.ReceiveTimeoutTransportException[cluster:monitor/nodes/liveness] request_id [31] timed out after [5000ms]
    Could not resolve placeholder
    分布式架构--第一篇--项目拆分(maven命令生成多模块项目)
    spring mvc官网下最新jar搭建框架-静态资源访问处理-注解-自动扫描
  • 原文地址:https://www.cnblogs.com/214txdy/p/14157756.html
Copyright © 2011-2022 走看看