首页 > 其他分享 >【模板】二维计算几何初步

【模板】二维计算几何初步

时间:2023-10-19 19:22:40浏览次数:46  
标签:const point cen rhs 二维 lhs 几何 return 模板

template <class T>
struct point {
    T x, y;
    point() : point(0, 0) {}
    point(T x, T y) : x(x), y(y) {}
    friend point operator+(const point &lhs, const point &rhs) {
        return { lhs.x + rhs.x, lhs.y + rhs.y };
    }
    friend point operator-(const point &lhs, const point &rhs) {
        return { lhs.x - rhs.x, lhs.y - rhs.y };
    }
    friend point operator*(const point &lhs, const T &k) {//数乘
        return { lhs.x * k, lhs.y * k };
    }
    friend T cross(const point &lhs, const point &rhs) {//叉积
        return lhs.x * rhs.y - rhs.x * lhs.y;
    }
    friend T operator*(const point &lhs, const point &rhs) {//向量内积
        return lhs.x * rhs.x + lhs.y * rhs.y;
    }
    friend T dist(const point &self) { return self * self; }//模长
    friend bool quad(const point &self) {//极角排序用于区分方向的象限(只判两个)
        return self.x <= 0 && self.y < 0 || self.x < 0 && self.y >= 0;
    }
    friend bool checkCross(const point &a, const point &b, const point &c, const point &d) {//两线段是否有交
        if (max(a.x, b.x) <= min(c.x, d.y) || max(c.x, d.x) <= min(a.x, b.x)) return 0;
        if (max(a.y, b.y) <= min(c.y, d.y) || max(c.y, d.y) <= min(a.y, b.y)) return 0;
        static const auto sgn = [&](const T &x) { return x == 0 ? 0 : (x < 0 ? -1 : 1); };
        return sgn(cross(a - c, d - c)) * sgn(cross(b - c, d - c)) < 0
            && sgn(cross(c - a, b - a)) * sgn(cross(d - a, b - a)) < 0;
    }
    friend bool operator==(const point &lhs, const point &rhs) {
        return lhs.x == rhs.x && lhs.y == rhs.y;
    }
    friend bool cmp(const point& a, const point& b) {
        return cross(a, b) ? cross(a, b) > 0 : dist(a) < dist(b);
    }
    friend bool operator<(const point& a,const point& b) {
        return a.x != b.x ? a.x < b.x : a.y < b.y;
    }
};
typedef point<LL> dot;
vector<dot> convexHull(vector<dot> a) {//凸包
    static dot stk[1 << 18];
    dot cen = *min_element(a.begin(), a.end());
    sort(a.begin(), a.end(),
        [&](const dot& a,const dot& b) { return cmp(a - cen, b - cen); });
    int top = 0;
    for (dot v: a){
        while (top >= 2 && cross(stk[top - 1] - stk[top], v - stk[top]) > 0)
            top--;
        stk[++top] = v;
    }
    return vector<dot>(stk + 1, stk + top + 1);
}
vector<dot> minkowski(const vector<dot>& a, const vector<dot>& b) {//闵可夫斯基和
    vector<dot> c = {a[0] + b[0]};
    static dot sa[1 << 18], sb[1 << 18];
    int n = a.size(), m = b.size();
    for (int i = 0; i < n; i++)
        sa[i] = a[(i + 1) % n] - a[i]; 
    for (int i = 0; i < m; i++)
        sb[i] = b[(i + 1) % m] - b[i]; 
    int i = 0, j = 0;
    for (int k = 1; k < n + m; k++){
        if (i < n && (j >= m || cmp(sa[i], sb[j])))
            c.push_back(c.back() + sa[i++]);
        else
            c.push_back(c.back() + sb[j++]);
    }
    return c;
}
bool checkIn(const vector<dot>& a, const dot& v) {//点是否在凸包内
    dot cen = a[0];
    if (cmp(a.back() - cen, v - cen))
        return 0;
    //if (cmp(v - cen, a[1] - cen)) return 0;
    if (cross(v - cen, a[1] - cen) ? cross(v - cen, a[1] - cen) > 0
                                   : dist(v - cen) > dist(a[1] - cen))
        return 0;
    auto p =
        lower_bound(a.begin() + 1, a.end(), v, [&](const dot& a,const dot& b) {
            return cmp(a - cen, b - cen);
        });
    return cross(*prev(p) - *p, v - *p) <= 0;
}

标签:const,point,cen,rhs,二维,lhs,几何,return,模板
From: https://www.cnblogs.com/caijianhong/p/template-geometry.html

相关文章

  • WPF绘图(一):几何(Geometry)与形状(Shape)
    1.Geometry在数学中,我们可以用一个方程描述圆:x2+y2=25。这个方程描述的是,一个半径为5,中心点在(0,0)的圆。这种纯数学的描述就是Geometry(几何)。但此时,这个“圆”我们是看不见,摸不着的。如果想要看到这个几何图形,就必须用画笔,颜色等信息,去“绘制”它。.Net中,Geometry类就是用于描述......
  • C++ 模板特化与偏特化:解析与应用
    引言在C++中,模板是一种非常强大的特性,它们允许我们编写通用、可重用的代码。但有时,我们需要为某些特定的数据类型或类提供特殊的实现,这时就需要使用到模板特化(TemplateSpecialization)和模板偏特化(PartialTemplateSpecialization)。本文将深入探讨这两者的概念、用法和注意事项......
  • C#判断当前时间是否在规定时间段范围内(二维数组超简版)
    直接上C#代码TimeSpannowTime=DateTime.Now.TimeOfDay;string[,]arr={{"7:50","8:10"},{"9:55","10:15"},{"13:55","14:10"},{"15:55","16:10"},{"18:55",......
  • 子矩阵的和(二维前缀和)
    一、算法描述上一篇文章介绍了一维前缀和,也就是一个数组的前n项和,这篇文章来介绍一下什么是二维前缀和。含义一维的是前n项的和,那么二维的情况下,表示的则是与左上角形成的矩形和。怎么求一维的递推关系式是s[i]=s[i-1]+a[i];,我们根据含义来思考二维的递推关系式,读......
  • C++模板笔记
    参考文章:https://juejin.cn/post/7078530622527897631模板是C++的泛型编程机制,这种机制可以最大程度复用代码并且不会增加运行时开销模板分为函数模板和类模板函数模板函数模板是对函数的参数进行泛型化,传递给模板函数的类型实参可以是类,也可以是整型值,还可以是模板名比如://......
  • 二分模板
    二分答案的写法有很多模板,但使用的情况各不相同前两种模板:都是while(l<r),但是会有区别的,区别在代码注释中有体现。后两种模板:都是while(l<=r),也是在返回上有区别。这是最大值最小intmain(){ intl; intr; while(l<r) { intmid=(l+r)/2; if(check()......
  • 一点模板
    线性素数筛:欧拉筛:定义数组prim[i]表示第i大的素数,isprim[i]表示i是否为素数(是否被筛过)从2~n遍历,if(!isprim[i])prim[++cnt]=i,如果遍历到i时i仍未被筛,则将i记录于prim数组中。接下来开始以i为基数筛除素数,我们发现:所有的合数都能被筛分割为若干数的积。所以无论i是否为......
  • ZXing.Net 的Core平台生成二维码
    一、引用二、代码帮助类///<summary>///ZXing.NET二维码帮助类///</summary>publicclassZXingHelper{///<summary>///站点二维码的目录///</summary>privatestaticstringQRCodeDirectory="QRCode";......
  • Thymeleaf 模板引擎
    Thymeleaf简介Thymeleaf(https://www.thymeleaf.org/Thymeleaf3.0.15)是一个XML/XHTML/HTML5模板引擎,可用于Web与非Web环境中的应用开发。它是一个开源的Java库,基于ApacheLicense2.0许可。Thymeleaf提供了一个用于整合SpringMVC的可选模块,在应用开发中,你可以使用Thymeleaf......
  • 考前模板整理
    有用的板子常用技巧inlinellread(){ llx=0,w=1; charch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-') w=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ x=(x......