计算几何学习笔记

基础部分

#include <bits/stdc++.h>
using namespace std;


#define type double
#define Vector Point
#define eps 1e-8

const double PI = 3.14159265358979323;


type Deg2Red(type deg){
	return (deg*PI/180.0);
}

type Rad2Deg(type rad){
	return rad*180.0/PI;
}


inline type Abs(type x){
	if(x<0)return -x;
	return x;
}


//二维点/二维向量 
struct Point{
	type x,y;
	Point(){
	}
	Point(type x,type y):x(x),y(y){
	}
	Point operator-(Point other){
		return Point(x-other.x,y-other.y);
	}
};

//向量点积 
type Dot(Vector a,Vector b){
	return a.x*b.x + a.y*b.y;
}

//向量叉积 
type Cross(Vector a,Vector b){
	return a.x*b.y - a.y*b.x;
}

//向量长度 
double Length(Vector a){
	return sqrt(a.x*a.x+a.y*a.y+0.0);
}

//两向量夹角 
type Angle(Vector a,Vector b){
	return acos(Dot(a,b) / (Length(a)*Length(b))+0.0);
}



多边形

//多边形面积(点必须按顺时针或逆时针顺序给出) 
type Area(Point* pts,int sz){
	type re=0;
	for(int i=0;i<sz;i++){
		re+=Cross(pts[(i+1)%sz],pts[i]);
	}
	re/=2.0;
	if(re<0)re=-re;
	return re;
}


平面最近点对(分治nlogn)。其实写得不优雅,要改掉。

//最近点对
type Nearest(Point* pts,int l,int r){
	if(r-l==2){
		return Length(pts[l+1]-pts[l]);
	}
	if(r-l==3){
		double re=min(Length(pts[l+1]-pts[l]),Length(pts[l+2]-pts[l]));
		re=min(re,Length(pts[l+2]-pts[l+1]));
		return re;
	}
    int mid = (l+r)>>1;
    type Minl=Nearest(pts,l,mid);
    type Minr=Nearest(pts,mid,r);
    type re = min(Minl,Minr);
    int cnt=0;
    int pos;
    //tmp暂存分割线附近的点
    pos=mid-1;
    while(1){
        if(pos<l)break;
        if(pts[pos].x>pts[mid].x-re){
            tmp[cnt++]=pts[pos];
            pos--;
        }else{
            break;
        }
    }
    pos=mid;
    while(1){
        if(pos>=r)break;
        if(pts[pos].x<pts[mid].x+re){
            tmp[cnt++]=pts[pos];
            pos++;
        }else{
            break;
        }
    }
    //感觉有点耍流氓,能不能不排序
    sort(tmp,tmp+cnt,byy);  //通过y排序

    for(int i=0;i<cnt;i++){
        for(int j=i+1;j<cnt;j++){
            if(tmp[j].y-tmp[i].y>re)break;
            re=min(re,Length(tmp[j]-tmp[i]));
        }
    }
    return re;
}







你可能感兴趣的:(计算几何学习笔记)