引言
参考刘汝佳大白书,有一些自己的修改,点、直线、圆的相关代码
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);}