zoukankan      html  css  js  c++  java
  • 计算几何初步模板

    点结构

    struct Point {
        double x;
        double y;
        Point(double a = 0, double b = 0) : x(a), y(b) {}
    };

    1、浮点数过滤

    int dbcmp(double x) {
        if(x > eps)    return 1;
        else if(x < -eps)    return -1;
        return 0;
    }

    2、线段求交点(简化一下可以用来判线段相交(规范相交))

    double det(double x1, double y1, double x2, double y2) {    //求叉积
        return x1*y2 - x2*y1;
    }
    
    double cross(Point a, Point b, Point c) {    //向量ab,和向量ac
        return det(b.x - a.x, b.y - a.y, c.x - a.x, c.y - a.y);
    }
    
    double dotdet(double x1, double y1, double x2, double y2) {    //点积
        return x1*x2 + y1*y2;
    }
    
    double dot(Point a, Point b, Point c) {
        return dotdet(b.x - a.x, b.y - a.y, c.x - a.x, c.y - a.y);
    }
    
    int betweenCmp(Point a, Point b, Point c) {    //判断a是不是在bc范围内
        return dbcmp(dot(a, b, c));
    }
    
    bool segcross(Point a, Point b, Point c, Point d) {
        double s1, s2;
        int d1, d2, d3, d4;
        d1 = dbcmp(s1 = cross(a, b, c));
        d2 = dbcmp(s2 = cross(a, b, d));
        d3 = dbcmp(cross(c, d, a));
        d4 = dbcmp(cross(c, d, b));
        if((d1^d2) == -2 && (d3^d4) == -2) {    //规范相交
            return true;
        }
        //非规范相交
        if((d1 == 0 && betweenCmp(c, a, b) <= 0) ||
           (d2 == 0 && betweenCmp(d, a, b) <= 0) ||
           (d3 == 0 && betweenCmp(a, c, d) <= 0) ||
           (d4 == 0 && betweenCmp(b, c, d) <= 0))
            return true;
        return false;
    }

      

    3、叉积求多边形面积

    double area(Point p[],int n) { //这里是相对于原点(0, 0),也可以在多边形上找一个点作为向量的起点
        double s = 0;
        int i;
        p[n].x = p[0].x;
        p[n].y = p[0].y;
        for(i = 0; i < n; ++i)
            s += det(p[i].x, p[i].y, p[i+1].x, p[i+1].y);
        return fabs(s / 2.0);
    }

    4、Graham-Scan法求凸包(黑书上的优化算法)

    void graham(int dir) {
        int i; t = 0;
        for(i = 0; i < n; ++i) {
            if(vis[i])    continue;
            while(t > 1 && dir*cross(p[st[t-1]], p[st[t]], p[i]) < 0)    --t;
            st[++t] = i;
        }
        for(i = 2; i < t; ++i)    vis[st[i]] = true;
    }
    
    //main
    
    for(i = 0; i < n; ++i) {
        scanf("%lf%lf", &p[i].x, &p[i].y);
    }
    sort(p, p + n, cmp);    //按y排序,如果相等,再按x排序
    memset(vis, 0, sizeof(vis));
    graham(1);
    for(i = 1; i <= t; ++i)    f[i] = st[i]; m = t;
    graham(-1);
    for(i = 1; i < t; ++i)    f[m + i] = st[t - i]; m += t-1;

    ps:暂时就这些,以后还会补充。

  • 相关阅读:
    模板与继承之艺术——空基类优化
    模板的多态(静多态)威力
    Linux在vi编辑模式下如何查找
    PHP var_dump() 函数
    PHP empty() 函数
    IOS连接代理后自动关闭
    charles:屏蔽web网页的抓包信息(proxy)
    Python-unittest单元测试框架总结
    fiddler过滤域名:仅显示指定的域名
    Java中System.getProperties()方法获取的系统属性
  • 原文地址:https://www.cnblogs.com/vongang/p/2442490.html
Copyright © 2011-2022 走看看