【笔记】二维几何模板

引言

参考刘汝佳大白书,有一些自己的修改,点、直线、圆的相关代码

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);}

猜你喜欢

转载自www.cnblogs.com/greenty1208/p/9387743.html
今日推荐