[模板仓库] 计算几何

未完待续

 

点:

1 struct point{
2     double x,y;
3     point operator + (point b){return (point){x+b.x,y+b.y};};
4     point operator - (point b){return (point){x-b.x,y-b.y};};
5     point operator * (double v){return (point){x*v,y*v};}
6     point operator / (double v){return (point){x/v,y/v};}
7 }p[mxn];

 

  结构体大法好

 

线:

  线段的话,开个结构体存两个端点

  直线的话:

 1 typedef point Vector;
 2 struct Line{
 3     point x;
 4     Vector v;
 5     double alpha;
 6      int id;
 7     void getang(){
 8        alpha=atan2(v.y,v.x);
 9        if(alpha<0)alpha+=pi*2;
10     }
11     bool operator < (Line b)const{return alpha<b.alpha;}
12 }a[mxn];

 

  存一个点+一个方向向量,alpha存相对于水平位置的角度。

  atan2()返回角度范围是-pi ~ +pi

 

向量运算:

  点距离:

1 double dist(point a,point b){
2     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
3 }

 

  长度:

1 double Len(Vector a){
2     return sqrt((a.x*a.x)+(a.y*a.y));
3 }

 

  点积:

1 double dot (point a,point b){return a.x*b.x+a.y*b.y;}

 

  叉积:

  向量a x 向量b ,若b在a的逆时针方向,返回结果为正;若b在a的顺时针方向,返回结果为负;同向或反向时结果为0

1 inline double Cross(Point a,Point b){return a.x*b.y-a.y*b.x;}

 

  向量逆时针旋转(弧度制):

1 point spin(point a,double ang){
2     return point(a.x*cos(ang)-a.y*sin(ang),a.x*sin(ang)+a.y*cos(ang));
3 }

 

 

 

  直线交点:

  利用三角形面积列出两个式子,消一下即可。

 ↑右边灰色部分应该是$ (k2-1)v2 $

1 Point intersec(Point a,Point v,Point b,Point w){
2     Point v1=a-b;
3     double t=Cross(w,v1)/Cross(v,w);
4     return a+v*t;
5 }

 

  判断两直线的位置关系:POJ1269 Intersecting Lines

 

半平面:

  用射线表示界线,射线的“左边”是半平面

 

圆:

  

1 struct cir{
2     double x,y;
3     double r;
4     point operator + (cir b){return (point){x+b.x,y+b.y};}
5     point operator - (cir b){return (point){x-b.x,y-b.y};}
6 }c[mxn];
7 inline bool cover(cir a,cir b){
8     return (a.r>=b.r+Len(a-b));
9 }

 

圆心角计算:Bzoj1313 [HAOI2008]下落的圆盘

最小圆覆盖:ZOJ1450 Minimal Circle

 

凸包:

  Graham算法:选定最靠边的一个点,将其他的所有点按向量极角排序,用单调栈维护。

  Andrew算法:按横坐标排序,先从左往右扫一遍搞出一个下凸壳,再从右往左扫一遍搞出一个上凸壳,用单调栈维护。

  cogs896 圈奶牛

 

半平面交

  将直线按极角排序,记录两两之间的交点。单调栈维护直线,若新加入的直线会覆盖旧直线,就把旧直线退栈

  Bzoj1007 [HNOI2008]水平可见直线

 

旋转卡壳

  有二十四种读音的神奇算法。

  Bzoj1185 [HNOI2007]最小矩形覆盖

 

扫描线:

  POJ1151 Atlantis

 

各种定理:

  picks定理:设平面直角坐标系中,一个三角形内部有a个整坐标点,它的三条边共经过了b个整坐标点,那么三角形面积$ S=a + b/2 -1 $

 

posted @ 2017-04-20 21:37  SilverNebula  阅读(200)  评论(0编辑  收藏  举报
AmazingCounters.com