计算几何基础 模板

计算几何拖了这么久,终于拖到省选前了。

参考:
https://oi.men.ci/geometry-notes/
https://www.cnblogs.com/fly-in-milkyway/p/10569895.html
https://blog.csdn.net/clover_hxy/article/details/53966405
https://www.cnblogs.com/lstoi/p/9791654.html


基础部分

#include <cmath>
#include <cstdio>
#include <cctype>
#include <vector>
#include <cstring>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=1e5+5;

const double eps=1e-10;

inline int dcmp(double x) {return fabs(x)<eps?0:x<0?-1:1;}

struct Vec
{
    double x,y;
    Vec(double x=0,double y=0):x(x),y(y) {}
    Vec operator +(const Vec &a)const {return Vec(x+a.x, y+a.y);}
    Vec operator -(const Vec &a)const {return Vec(x-a.x, y-a.y);}
    Vec operator *(const double p)const {return Vec(x*p, y*p);}

    double operator *(const Vec &a)const {return x*a.y-y*a.x;}//cross product
    bool operator <(const Vec &a)const {return x<a.x||(x==a.x&&y<a.y);}
    bool operator ==(const Vec &a)const {return !dcmp(x-a.x)&&!dcmp(y-a.y);}

    double Norm() {return x*x+y*y;}//范数
    double Length() {return sqrt(x*x+y*y);}//模长
    double Dot(Vec a) {return x*a.x+y*a.y;}//dot product
    double Angle(Vec a) {return acos(Dot(a)/Length()/a.Length());}//两向量夹角
    Vec Normal() {double t=Length(); return Vec(-y/t,x/t);}//单位法向量
    Vec Rotate(double rad) {return Vec(x*cos(rad)-y*sin(rad),x*sin(rad)+y*cos(rad));}
};
typedef Vec Point;

struct Line
{
    Point a; Vec v;
    Line(Point a,Vec v):a(a),v(v) {}

    bool OnLine(const Point &p) {return !dcmp((a-p)*v);}//!dcmp((a-p)*(b-p))
    bool OnSegment(const Point &p) {return !dcmp((a-p)*v)&&dcmp((a-p).Dot(a+v-p))<=0;}//PA*PB<=0
    int Relation(const Line &l)//直线之间的关系 0:平行 1:相交 2:重合(无数个交点)
    {
        return dcmp(v*l.v)?1:dcmp(v*(a-l.a))?0:2;
    }
    Point Intersection(const Line &l)//直线交点
    {
        return a+v*(((a-l.a)*l.v)/(v*l.v));
    }
};

inline bool cmp(const Point &a,const Point &b) {return a.x==b.x?a.y<b.y:a.x<b.x;}

struct Polygon
{
    int sk[N];
    std::vector<Point> ps;

    bool Include(const Point &p)//点在多边形内
    {
        int cnt=0;
        for(int i=0,lim=ps.size(); i<lim; ++i)
        {
            const Point a=ps[i],b=ps[i+1==lim?0:i+1];
            if(Line(a,b-a).OnSegment(p)) return 1;
            double d1=a.y-p.y,d2=b.y-p.y,tmp=(a-p)*(b-p);
            if((tmp<0&&d1<0&&d2>=0)||(tmp>0&&d1>=0&&d2<0)) ++cnt;
        }
        return cnt&1;
    }
    double Area()//多边形有向面积(逆时针为正,顺时针为负)
    {
        double res=0;
        for(int i=0,lim=ps.size(); i<lim; ++i)
            res+=ps[i]*ps[i+1==lim?0:i+1];
        return res*0.5;
    }
    int Convex()//求凸包 存在sk[]里
    {
        std::sort(ps.begin(),ps.end(),cmp);
        int top=1,n=ps.size(); sk[1]=0;
        for(int i=1; i<n; ++i)
        {
            while(top>=2 && (ps[sk[top]]-ps[sk[top-1]])*(ps[i]-ps[sk[top-1]])<=0) --top;
            sk[++top]=i;
        }
        int k=top;
        for(int i=n-2; ~i; --i)
        {
            while(top>k && (ps[sk[top]]-ps[sk[top-1]])*(ps[i]-ps[sk[top-1]])<=0) --top;
            sk[++top]=i;
        }
        return top;
    }
};

int main()
{
    return 0;
}

凸包


极角排序


最小圆覆盖


旋转卡壳


半平面交

原文地址:https://www.cnblogs.com/SovietPower/p/10593432.html

时间: 2024-10-24 13:52:59

计算几何基础 模板的相关文章

知识点 - 计算几何基础

知识点 - 计算几何基础 讲义 点 我们把点 \(\mathbf r\) 看成从 \(\mathbf 0\) 到 \(\mathbf r\)的向量 \(\vec{\mathbf r}\) #define ftype long double struct point2d { ftype x, y; point2d() {} point2d(ftype x, ftype y): x(x), y(y) {} point2d& operator+=(const point2d &t) { x +=

nyis oj 68 三点顺序 (计算几何基础)

三点顺序 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描写叙述 如今给你不共线的三个点A,B,C的坐标,它们一定能组成一个三角形,如今让你推断A,B,C是顺时针给出的还是逆时针给出的? 如: 图1:顺时针给出 图2:逆时针给出 <图1>                   <图2> 输入 每行是一组測试数据,有6个整数x1,y1,x2,y2,x3,y3分别表示A,B,C三个点的横纵坐标.(坐标值都在0到10000之间) 输入0 0 0 0 0 0表示输入

计算几何基础——【点积和叉积的用处】

计算几何是算法竞赛的一大块,而叉积是计算机和的基础. 首先叉积是计算说向量之间的叉积,那么我们可以这样定义向量,以及向量的运算符重载. struct Point { double x,y; Point(double x=0,double y=0):x(x),y(y) {} }; typedef Point Vector; Vector operator + (Vector A,Vector B) { return Vector(A.x+B.x,A.y+B.y); } Vector operato

【kuangbin专题】计算几何基础(极角相关)

[POJ 1696] Space Ants [题目大意] 给定多个点,对他们按照下面的规则排序,每个都在前一个点组成的左边,并且连线不相交(典型如图) [题目分析] 不断进行极角排序,不断选取一定区域内最符合要求的解 [代码] 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #define ll double 5 using namespace std; 6 const double eps

计算几何基础(模板)

1.多边形面积计算 1 double S(Point p[],int n) 2 { 3 double ans = 0; 4 p[n] = p[0]; 5 for(int i=1;i<n;i++) 6 ans += cross(p[0],p[i],p[i+1]); 7 if(ans < 0) ans = -ans; 8 return ans / 2.0; 9 } 2.求凸包 1 bool cmp(Point A,Point B) 2 { 3 double k = cross(MinA,A,B);

BZOJ_1610_[Usaco2008_Feb]_Line连线游戏_(计算几何基础+暴力)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1610 给出n个点,问两两确定的直线中,斜率不同的共有多少条. 分析 暴力枚举直线,算出来斜率放在k数组里面(斜率不存在记为INF),然后去个重统计个数就行了. 其实特水... 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=200+5; 5 const double eps=1e-8,INF=0x7f

计算几何及其应用——计算几何基础

写在前面:当时开计算几何这个专题神奇的从解析几何开始了,然后最近发现<计算几何及应用(金博)>这本书前面那章忽略掉了一些重要的东西比如说点定位.半平面相交之类的东西,恰好还有一些和计算几何扯上边但是不需要算法的简单题目没有整理,故在此开辟一块小空间. 我们再来看一道有关几何的问题.(Problem source:hdu2073)    数理分析:虽然这道题异常的简单,基本算不上计算几何这个专题当中的题目,但是把它拿到这里来,是源于这道简单几何题的思路其实体现了计算几何整个体系中比较重要的思维.

UVA 10652 Board Wrapping(计算几何基础,求凸包)

题目链接:传送门 分析: 没有什么好说的就是求一个凸包就好了.可以当作模板. 代码如下: #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; const double eps = 1e-10; //判断符号,提高精度 int dcmp(double x){ if(fab

【习题整理】计算几何基础

bzoj1074[Scoi2007]折纸 思路:考虑倒着做,每次将在折叠的直线右边的扔掉,左边的点再对称一次加入: 算几知识:求向量关于法向量的对称向量 点$A$关于点$B$对称的点$C = 2B - A$ 如果要求$\vec{A}$关于法向量$\vec{l}$的对称向量$\vec{A'}$: 可以考虑都平移到原点 利用点积求出$\vec{A}$在$\vec{l}$上的投影点$D$, 再将点$A$关于$D$对称到$A'$: $A'$的坐标就是向量$\vec{A'}$ 1 #include<bit