浅谈计算几何的模板集合

管用!

代码

压缩了的

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
const int eps=1e-10;
const double PI=acos(double(-1));
struct Point 
{
    double x,y;
    double len() {return sqrt(x*x+y*y);}
    Point(double _=.0,double __=.0):x(_),y(__) {}//生成点
    double ang() {return atan2(y,x);} 
}//点 
Point operator +(const Point &r,const Point &s) 
{return Point(r.x+s.x,r.y+s.y);}
Point operator -(const Point &r,const Point &s) 
{return Point(r.x-s.x,r.y-s.y);}
Point operator *(const Point &r,double s) 
{return Point(r.x*s,r.y*s);}
Point operator /(const Point &r,double s) 
{return Point(r.x/s,r.y/s);}//基本运算 
int sign(double a)
{return (a>eps)?1:(a<-eps)?-1:0;}//判断正负 
double dot(const Point &r, const Point &s) 
{return r.x*s.x+r.y*s.y;}//点积 
double cross(const Point &r, const Point &s) 
{return r.x*s.y-r.y*s.x;}//叉积
double ang(const Point &a)
{return atan2(a.y,a.x);}//注意是反的! 
struct Line 
{
    Point p;
    Point u;
    double ang;
    Line(){}
    Line(Point p, Point u):p(p),u(u),ang(u.ang()){}
};//线 
bool operator <(const Line &r,const Line &s) 
{return r.ang<s.ang;}
bool operator ==(const Line &r, const Line &s) 
{return sign(r.ang-s.ang)==0;}
bool onleft(const Point &a, const Point &b, const Point &p) 
{return cross(b-a,p-a)>0;}
bool onleft(const Line &l,const Point &p) 
{return cross(l.u,p-l.p)>0;}
Point line_intersect(Point P, Point u, Point Q, Point v) 
{
    Point w=P-Q;
    double t=cross(v,w)/cross(u,v);
    return P+u*t;
}//直线求交
Point line_intersect (const Line &a, const Line &b) 
{return line_intersect (a.p,a.u,b.p,b.u);}
int half_plane_intersect(vector<Line> &h) 
{
    sort(h.begin(),h.end());
    int n=(int)h.size();
    int first,last;
    Point *p=new Point[n];
    Line *q=new Line[n];
    q[first=last=0]=h[0];
    for (int i=1;i<n;i++) 
    {
        while(first<last&&!onleft(h[i],p[last-1])) last--;
        while(first<last&&!onleft(h[i],p[first])) first++;
        q[++last]=h[i];
        if (fabs(cross(q[last].u,q[last-1].u))<eps) 
        {
            last--;
            if (onleft(q[last],h[i].p)) q[last]=h[i];
        }
        if (first<last) p[last-1]=line_intersect(q[last-1],q[last]);
    }
    while(first<last && !onleft(q[first],p[last-1])) last--;
    if (last-first<=1) return 0;
    p[last]=line_intersect(q[last],q[first]);
    return last-first+1;
}//半平面交 
bool seg_intersect(Point A, Point B, Point C, Point D) 
{
    double c1=cross(B-A,C-A),c2=cross(B-A,D-A);
    double c3=cross(D-C,A-C),c4=cross(D-C,B-C);
    return sign(c1)*sign(c2)<0&&sign(c3)*sign(c4)<0;
}//线段判交
bool point_on_line(const Point &p,const Point &A,const Point &B) 
{
    return sign(cross(B-A, p-A))==0&&sign(dot(A-p,B-p))<=0;
}
bool in_polygon (const Point &p, const vector<Point> &poly) 
{
    int n=(int)poly.size();
    int counter=0;
    for (int i=0;i<n;++i) 
    {
        Point a=poly[i],b=poly[(i+1)%n];
        if (point_on_line(p,a,b)) return true; // bounded included
        int x=sign(cross(p-a,b-a));
        int y=sign(a.y-p.y);
        int z=sign(b.y-p.y);
        if (x>0&&y<=0&&z>0) counter++;
        if (x<0&&z<=0&&y>0) counter--;
    }
    return counter!=0;
}//点在多边形内 
double area(const vector<Point> &poly) 
{
    double rt=0.0;
    int n=(int)poly.size();
    for (int i=0;i<n;i++) 
    rt+=cross(poly[i],poly[(i+1)%n]);
    return fabs(rt/2.0);
}//多边形的面积 
vector<Point> convex(vector<Point> pts) 
{
    int n=(int)pts.size();
    int m=0;
    vector<Point> cvx;
    sort(pts.begin(),pts.end());
    for(int i=0;i<n;i++) 
    {
        while(m>1&&onleft(cvx[m-2],cvx[m-1],pts[i])) 
        {cvx.pop_back();m--;}
        cvx.push_back(pts[i]);
        m++;
    }
    int k=m;
    for (int i=n-2;i>=0;i--) 
    {
        while(m > k && onleft(cvx[m - 2], cvx[m - 1], pts[i])) 
        {cvx.pop_back();m--;}
        cvx.push_back(pts[i]);
        m++;
    }
    if(n>1) 
    {m--;cvx.pop_back();}
    return cvx;
}//凸包 
int main()
{
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值