计算几何初步

终于开始入手计算几何了呀
用了一天学了挺多知识了,打了一些模板题
比较简单也就不一一列举了
这里先放出来一个可能有所错漏的板子
会慢慢改动的
模板十分简洁!!!

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define db double
using namespace std;
const int N = 1e5 + 10;
const db eps = 1e-8,PI = acos(-1);
int dcmp(db x){if(fabs(x) < eps) return 0;return x > 0 ? 1 : -1;}
struct pt{
    db x,y;
    pt(){}
    pt(db x,db y): x(x),y(y){}
};
pt operator - (pt a,pt b){return pt(a.x - b.x,a.y - b.y);}
pt operator + (pt a,pt b){return pt(a.x + b.x,a.y + a.y);}
pt operator * (pt a,db d){return pt(a.x * d,a.y * d);}
db operator * (pt a,pt b){return a.x * b.x + a.y * b.y;}
db cs(pt a,pt b){return a.x * b.y - a.y * b.x;}
db cs(pt a,pt b,pt c){return (b - a).x * (c - a).y - (b - a).y * (c - a).x;}
//vector_rotate
pt vrt(pt a,db t){return pt(a.x * cos(t) - a.y * sin(t),a.x * sin(t) + a.y * cos(t));}
struct line{
    pt x,y;
    db deg;
    line(){}
    line(pt x,pt y) : x(x),y(y){deg = atan2((y - x).y,(y - x).x);}
};
//is_on_Right
bool oR(pt p,line a){return dcmp(cs(p - a.x,a.y - a.x)) >= 0;}
pt lip(line a,line b){//line_intersection_point
    pt v = a.y - a.x,u = b.y - b.x,w = a.x - b.x;
    db t = cs(w,u) / cs(u,v);
    return a.x + v * t;
}
db cpa(pt p[],int n){//convex_polygon_area
    db ans = 0;
    for(int i = 1;i <= n - 2;i ++){
        ans += cs(p[0],p[i],p[i + 1]);
    }
    return ans / 2.0;
}

//凸包
bool Acmp(pt a,pt b){return a.x == b.x ? a.y < b.y : a.x < b.x;}
int Andrew(pt p[],int n,pt s[],int m){
    sort(p + 1,p + 1 + n,Acmp);
    m = 0;
    for(int i = 1;i <= n;i ++){
        while(m > 1 && cs(s[m - 2],s[m - 1],p[i]) < 0) m --;
        s[m ++] = p[i];
    }
    int k = m;
    for(int i = n - 1;i >= 1;i --){
        while(m > k && cs(s[m - 2],s[m - 1],p[i]) < 0) m --;
        s[m ++] = p[i];
    }
    if(n > 1) m --;
    return m;
}

//旋转卡壳
//get_distance
int gd(pt a){return a.x * a.x + a.y * a.y;}
int Rc(pt s[],int m){//Rotating_calipers
    int cur = 1,ans = 0;
    for(int i = 0;i < m;i ++){
        while(cs(s[i],s[cur],s[i + 1]) < cs(s[i],s[cur + 1],s[i + 1])) cur = (cur + 1) % m;
        ans = max(ans ,max(gd(s[cur] - s[i]),gd(s[cur] - s[i + 1])));
    }
    return ans;
}

//半平面交
bool HPIcmp(line a,line b){
    if(dcmp(a.deg - b.deg) == 0) return oR(b.x,a);
    return a.deg < b.deg;
}
int HPI(line L[],line q[],pt s[],int cnt){//half_plane_intersection
    sort(L + 1,L + cnt + 1,HPIcmp);
    int l = 1,r = 1;
    q[1] = L[1];
    for(int i = 2;i <= cnt;i ++){
        if(!dcmp(L[i].deg - L[i - 1].deg)) continue;
        while(l < r && oR(s[r - 1],L[i])) r --;
        while(l < r && oR(s[l],L[i])) l ++;
        q[++ r] = L[i];
        if(l < r) s[r - 1] = lip(q[r],q[r - 1]);
    }
    while(l < r && oR(s[r - 1],q[l])) r --;
    while(l < r && oR(s[l],q[r])) l ++;
    s[r] = lip(q[l],q[r]);
    if(r - l + 1 <= 1) return 0;
    return r - l + 1;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值