1. 程式人生 > >【筆記】二維幾何模板

【筆記】二維幾何模板

參考 uva11178 計算 end 必備 href 不同 void 方法

引言

參考劉汝佳大白書,有一些自己的修改,點、直線、圓的相關代碼

AC代碼匯總

UVA11178 Morley定理
LA 3263 好看的一筆畫

模板

Part 0 基本部分

計算幾何必備零散知識
精度

const double eps = 1e-9;
  • 圓周率
const double PI = acos(-1);
  • 比較函數
int dcmp(double x){return fabs(x)<eps?0:(x<0?-1:1);}

Part 1 結構體

# define Vector Point
struct Point{
    double x,y;
    Point(double x=0,double y=0) :x(x),y(y){}
    friend Vector operator + (Vector A,Vector B){ return Vector(A.x + B.x , A.y + B.y);}
    friend Vector operator - (Point A,Point B){ return Vector(A.x - B.x , A.y - B.y);}
    friend Vector operator * (Vector A,double p) {return Vector(A.x*p , A.y*p);}
    friend Vector operator / (Vector A,double p) {return Vector(A.x/p,A.y/p);}
    friend bool operator < (Point a,Point b){return dcmp(a.x-b.x)<0||(dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)<0);}
    friend bool operator == (const Point &a,const  Point &b){return (dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0);}
    inline void input(){cin>>x>>y;}
};

向量和點用同一個結構體,但意義不同

struct Line{
    Point p;Vector v;double ang;    
    Line(){}                                                                      
    Line(Point p,Vector v): p(p),v(v){v = v/(sqrt(v.x*v.x+v.y*v.y));ang = atan2(v.y,v.x);}
    bool operator < (const Line& L) const {return ang < L.ang;}
    Point point(double t) { return p + v*t; }
    void input(){p.input();v.input();}
};

v為方向向量,在構造函數中會將其轉化成單位向量
point 方法:已知求距離p點r單位有向距離的直線上的點
重載小於:按極角排序

struct Circle{
    Point o;double r;
    Circle(){};
    Circle(Point o,double r):o(o),r(r){}
    Point point(double a){return Point(o.x + cos(a)*r, o.y + sin(a)*r);}
    void input(){o.input();cin>>r;}
};

point方法:已知角度,求圓上的點

Part 2 函數

點,直線,圓的相關函數

Point(Vector) & Point(Vector)

  • 點積
double Dot(Vector A,Vector B){return A.x*B.x + A.y*B.y;}
  • 叉積
double Cross(Vector A,Vector B){return A.x*B.y - A.y*B.x;}
  • 向量長度(兩點相減)
double Length(Vector A) {return sqrt(Dot(A,A));}
  • 兩向量轉角
double Angle(Vector A,Vector B) {return acos(Dot(A,B)/Length(A)/Length(B));}
  • 向量極角[-PI,PI)
double Angle(Vector v){return atan2(v.y,v.x);}
  • 向量旋轉
Vector Rotate(Vector A, double rad){return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));}
  • 三角形面積
double Tri_Area(Point A,Point B,Point C){return Cross(B-A,C-A)/2;}
  • 兩點中點
Point Mid_Point_Point(Point A,Point B){return Point((A.x+B.x)/2,(A.y+B.y)/2);}

【筆記】二維幾何模板