二维计算几何模板(点,线)

#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<queue>
#include<vector>
#include<map>
#include<stack>
#include<set>
#define e exp(1.0); //2.718281828
#define mod 1000000007
#define INF 0x7fffffff
#define inf 0x3f3f3f3f
typedef long long LL;
using namespace std;

#define zero(x) (((x)>0?(x):(-x))<eps)
const double eps=1e-8;
const double pi=acos(-1.0);

int cmp(double x){
    if(fabs(x)<eps) return 0;
    if(x>0) return 1;
    return -1;
}
inline double sqr(double x){
    return x*x;
}
struct point{
    double x,y;
    point(){};
    point(double a,double b):x(a),y(b){};
    void input(){
        scanf("%lf %lf",&x,&y);
    }
    friend point operator + (const point &a,const point &b){
        return point(a.x+b.x,a.y+b.y);
    }
    friend point operator - (const point &a,const point &b){
        return point(a.x-b.x,a.y-b.y);
    }
    friend bool operator == (const point &a,const point &b){
        return cmp(a.x-b.x)==0&&cmp(a.y-b.y)==0;
    }
    friend point operator * (const point &a,const double &b){
        return point(a.x*b,a.y*b);
    }
    friend point operator * (const double &a,const point &b){
        return point(a*b.x,a*b.y);
    }
    friend point operator / (const point &a,const double &b){
        return point(a.x/b,a.y/b);
    }
    double norm(){
        return sqrt(sqr(x)+sqr(y));
    }
};
//计算两个向量的叉积
double det(const point &a,const point &b){
    return a.x*b.y-a.y*b.x;
}
//计算两个点的点积
double dot(const point &a,const point &b){
    return a.x*b.x+a.y*b.y;
}
//计算两个点的距离
double dist(const point &a,const point &b){
    return (a-b).norm();
}
//op沿远点逆时针旋转角度A
point rotate_point(const point &p,double A){
    double tx=p.x,ty=p.y;
    return point(tx*cos(A)-ty*sin(A),tx*sin(A)+ty*cos(A));
}
//判断数k的符号 -1负数 1正数 0零
int dcmp(double k){
    return k<-eps?-1:k>eps?1:0;
}
double cross(const point &a,const point &b){
    return a.x*b.y-a.y*b.x;
}
double abs(const point &o){
    return sqrt(dot(o,o));
}

struct line{
    point a,b;
    line(){};
    line(point x,point y):a(x),b(y){};
};
//两个点生成一个线段/直线
line point_make_pair(const point a,const point b){
    return line(a,b);
}
//p点到线段st的垂足,保存在cp里
void PointProjLine(const point p,const point s,const point t,point &cp){
    double r=dot((t-s),(p-s))/dot(t-s,t-s);
    cp=s+r*(t-s);
}
//判断p点是否在线段st上(包括端点)
bool PointOnSegment(point p,point s,point t){
    return cmp(det(p-s,t-s))==0 && cmp(dot(p-s,p-t))<=0;
}
//判断线段a,b是否平行
bool parallel(line a,line b){
    return !cmp(det(a.a-a.b,b.a-b.b));
}
//判断a,b是否相交,交点保存在res
bool line_make_point(line a,line b,point &res){
    if(parallel(a,b)) return false;
    double s1=det(a.a-b.a,b.b-b.a);
    double s2=det(a.b-b.a,b.b-b.a);
    res=(s1*a.b-s2*a.a)/(s1-s2);
    return true;
}
//将线段a沿法向量平移len的线段
line move_d(line a,const double &len){
    point d=a.b-a.a;
    d=d/d.norm();
    d=rotate_point(d,pi/2);
    return line(a.a+d*len,a.b+d*len);
}


//p0p1 X p0p2
double xmult(point p0,point p1,point p2) {
    return det((p1-p0),(p2-p0));
}
double xmult(double x1,double y1,double x2,double y2,double x0,double y0){
    return (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0);
}
//dot(p1-p0).(p2-p0)
double dmult(point p1,point p2,point p0){
    return (p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);
}
double dmult(double x1,double y1,double x2,double y2,double x0,double y0){
    return (x1-x0)*(x2-x0)+(y1-y0)*(y2-y0);
}
//判断3点是否共线
bool dots_inline(point p1,point p2,point p3){
    return zero(xmult(p1,p2,p3));
}
//判断点是否在线段上,包括端点
bool dot_online_in(point p,line l){
    return zero(xmult(p,l.a,l.b))&&(l.a.x-p.x)*(l.b.x-p.x)<eps&&(l.a.y-p.y)*(l.b.y-p.y)<eps;
}
//判断点是否在线段上,不包括端点
bool dot_online_ex(point p,line l){
    return dot_online_in(p,l)&&(!zero(p.x-l.a.x)||!zero(p.y-l.a.y))&&(!zero(p.x-l.b.x)||!zero(p.y-l.b.y));
}
//判断两点是否在线段同一侧(点在直线上时为0)
bool same_side(point p1,point p2,line l){
    return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)>eps;
}
//判断两点是否在线段异侧(点在直线上时为0)
bool opposite_side(point p1,point p2,line l){
    return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)<-eps;
}
//点关于直线的对称点
point symmetric_point(point p1,point l1,point l2){
    point ret;
    if(l1.x>l2.x-eps&&l1.x<l2.x+eps){
        ret.x=(2*l1.x-p1.x);
        ret.y=p1.y;
    }
    else{
        double k=(l1.y-l2.y)/(l1.x-l2.x);
        ret.x=(2*k*k*l1.x+2*k*p1.y-2*k*l1.y-k*k*p1.x+p1.x)/(1+k*k);
        ret.y=p1.y-(ret.x-p1.x)/k;
    }
    return ret;
}
//判断两线段相交,包括端点和部分重合
bool intersect_in(line u,line v){
    if(!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b))
        return !same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u);
    return dot_online_in(u.a,v)||dot_online_in(u.b,v)||dot_online_in(v.a,u)||dot_online_in(v.b,u);
}
//判断两线段相交,不包括端点和部分重合
bool intersect_ex(line u,line v){
    return opposite_side(u.a,u.b,v)&&opposite_side(v.a,v.b,u);
}
//判断直线l1和线段l2是否相交
bool Seg_inter_line(line l1,line l2) {
    return cmp(xmult(l2.a,l1.a,l1.b))*cmp(xmult(l2.b,l1.a,l1.b)) <= 0;
}
//p点到线段st的距离
double dis_point_segment(const point p,const point s,const point t){
    if(cmp(dot(p-s,t-s))<0) return (p-s).norm();
    if(cmp(dot(p-t,s-t))<0) return (p-t).norm();
    return fabs(det(s-p,t-p)/dist(t-s,t-s));
}
//p点到直线st的距离
double disptoline(point p,line l){
    return fabs(xmult(p,l.a,l.b))/dist(l.a,l.b);
}

const int maxn=1000;
struct polygon{
    int n;
    point a[maxn];
    polygon(){};
//多边形的周长
    double perimeter(){
        double sum=0;
        a[n]=a[0];
        for(int i=0;i<n;i++) sum+=(a[i+1]-a[i]).norm();
        return sum;
    }
//多边形的面积
    double area(){
        double sum=0;
        a[n]=a[0];
        for(int i=0;i<n;i++) sum+=det(a[i+1],a[i]);
        return sum/2;
    }
//判断点是否在多边形内,0多边形外,1多边形内,2边界上
    int Point_In(point t){
        int num=0;
        a[n]=a[0];
        for(int i=0;i<n;i++){
            if(PointOnSegment(t,a[i],a[i+1])) return 2;
            int k=cmp(det(a[i+1]-a[i],t-a[i]));
            int d1=cmp(a[i].y-t.y);
            int d2=cmp(a[i+1].y-t.y);
            if(k>0&&d1<=0&&d2>0) num++;
            if(k<0&&d2<=0&&d1>0) num--;
        }
        return num!=0;
    }
};

struct Circle{
    point p;
    double r;
    bool operator < (const Circle &o) const{
        if(dcmp(r-o.r)!=0) return dcmp(r-o.r)==-1;
        if(dcmp(p.x-o.p.x)!=0){
            return dcmp(p.x-o.p.x)==-1;
        }
        return dcmp(p.y-o.p.y)==-1;
    }
    bool operator == (const Circle &o) const{
        return dcmp(r-o.r)==0&&dcmp(p.x-o.p.x)==0&&dcmp(p.y-o.p.y)==0;
    }
};
/*************************************/
int main(){
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值