1. 程式人生 > >[學習筆記]計算幾何

[學習筆記]計算幾何

堪稱明明看得見,就是寫不出的一類噁心題。

通常細節頗多。

一旦方法選擇合適,程式碼量和效率都會提升不少。

 

推薦:

「計算幾何」計算幾何從入門到入土

(以下圖片均來自此部落格)

 

struct po{
    double x,y;
    po(){}
    po(double xx,double yy){
        x=xx;y=yy;
    }
    po friend operator +(po a,po b){
        return po(a.x+b.x,a.y+b.y);
    }
    po friend 
operator -(po a,po b){ return po(a.x-b.x,a.y-b.y); } };

(加減為了向量方便賦值)

 

兩(多)點距離公式

double dis(po a,po b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
距離公式

 

中點

(x=(x1+x2)/2,y=(y1+y2)/2)

向量

struct vec{
    double x,y;
    vec(){}
    vec(po a){
        x
=a.x,y=a.y; } double len(){ return sqrt(x*x+y*y); } };
向量

向量加減和數乘略了。

len是向量的模長。

點積

double dot(vec a,vec b){
    return a.x*b.x+a.y*b.y;
}
點積

 

點積用處:可以通過兩個向量的點積正負,判斷向量夾角是銳角、直角、鈍角

叉積

double cross(vec a,vec b){
    return a.x*b.y-a.y*b.x;
}
叉積

 

意義,兩個向量構成的平行四邊形的有向面積

AxB ,如果有A在B的逆時針方向(不超180度),那麼面積是負的。否則是正的。

 

向量旋轉

https://zhidao.baidu.com/question/562549647.html

 

常用方法

精度控制

設定eps 1e-7~1e-10

int Fabs(double t){
    if(fabs(t)<eps) return 0;
    if(t>0) return 1;
    return -1;
}
Fabs

 

 

點到直線距離(給出三個點)

叉積算平行四邊形面積,然後除以底的長度,得到高(距離)

double hei(po p,po a,po b){
    vec t1=vec(a-b),t2=vec(p-b);
    return fabs(cross(t1,t2))/dis(a,b);
}
點到直線距離

 

 

點到線段距離

點積判斷和端點形成的角是否是鈍角。是鈍角,就只能是和線段兩個端點的距離取min

 

 

線段是否相交

 跨立實驗

如果兩個線段端點互相都在對方的兩側,那麼相交。

 

點在多邊形內部

 

求任意多邊形面積

 

多邊形重心

 

 

凸包

 

Graham 演算法

 

旋轉卡殼

 

 

例題: