zoukankan      html  css  js  c++  java
  • 计算几何模板

    基础模板

      1 const double eps = 1e-10;
      2 const double pi = 3.1415926535897 ;
      3 struct Point
      4 {
      5     double x, y;
      6     Point(double x = 0, double y = 0):x(x), y(y){}
      7 };
      8 typedef Point Vector;
      9 
     10 struct Line//有向直线
     11 {
     12     Point P;//直线上任意一点
     13     Vector v;//方向向量(左边就是对应的半平面)
     14     double ang;//极角,即从x正半轴旋转到向量v所需要的角(弧度)
     15     Line(Point P, Vector v):P(P), v(v){ang = Angle(v);}
     16     bool operator < (const Line& L)const
     17     {
     18         return ang < L.ang;
     19     }
     20 };
     21 Vector operator + (Vector A, Vector B){return Vector(A.x+B.x, A.y+B.y);}//向量+向量=向量;点+向量=向量
     22 Vector operator - (Vector A, Vector B){return Vector(A.x-B.x, A.y-B.y);}//点-点=向量
     23 Vector operator * (Vector A, double p){return Vector(A.x*p, A.y*p);}//向量*数=向量
     24 Vector operator / (Vector A, double p){return Vector(A.x/p, A.y/p);}//向量/数=向量
     25 bool operator < (const Point& a, const Point& b)
     26 {
     27     return a.x < b.x || (a.x == b.x && a.y < b.y);
     28 }
     29 int dcmp(double x)//三态函数,高精度判断
     30 {
     31     if(fabs(x) < eps)return 0; else return x < 0 ? -1 : 1;
     32 }
     33 bool operator == (const Point& a, const Point& b)
     34 {
     35     return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y) == 0;
     36 }
     37 double Dot(Vector A, Vector B){return A.x*B.x + A.y*B.y;}//点积
     38 double Length(Vector A){return sqrt(Dot(A, A));}//长度
     39 double Angle(Vector A){return atan2(A.y, A.x);}//向量A的极角(弧度)
     40 double Angle(Vector A, Vector B){return acos(Dot(A, B) / Length(A) / Length(B));}//向量A,B夹角
     41 double Cross(Vector A, Vector B){return A.x*B.y - A.y*B.x;}//叉积
     42 double Area2(Point A, Point B, Point C){return Cross(B-A, C-A);}//三角形有向面积的两倍
     43 Vector Rotate(Vector A, double rad)
     44 //向量A逆时针旋转rad(弧度)
     45 {
     46     return Vector(A.x*cos(rad)-A.y*sin(rad), A.x*sin(rad)+A.y*cos(rad));
     47 }
     48 Vector Normal(Vector A)
     49 //返回A的单位法线,调用前保证A非零
     50 {
     51     double L = Length(A);
     52     return Vector(-A.y/L, A.x/L);
     53 }
     54 
     55 Point GetlineIntersection(Point P, Vector v, Point Q, Vector w)//(参数式)
     56 //求直线P+tv和Q+tw交点(t为参数)。调用前确保有交点,无交点当且仅当Cross(v, w) = 0;
     57 {
     58     Vector u = P - Q;
     59     double t = Cross(w, u) / Cross(v, w);
     60     return P + v*t;
     61 }
     62 Point GetlineIntersectionB(Point P, Point X, Point Q, Point Y)//(两点式)
     63 //求直线PX和QY交点(t为参数)。调用前确保有交点,无交点当且仅当Cross(v, w) = 0;
     64 {
     65     Vector v = X - P, w = Y - Q;
     66     return GetlineIntersection(P, v, Q, w);
     67 }
     68 double DistanceToLine(Point P, Point A, Point B)
     69 //点P到直线AB的距离
     70 {
     71     Vector v1 = B - A, v2 = P - A;
     72     return fabs(Cross(v1, v2) / Length(v1));
     73 }
     74 double DistanceToSegment(Point P, Point A, Point B)
     75 //点P到线段AB的距离
     76 {
     77     if(A == B)return Length(P-A);
     78     Vector v1 = B - A, v2 = P - A, v3 = P - B;
     79     if(dcmp(Dot(v1, v2)) < 0)return Length(v2);
     80     else if(dcmp(Dot(v1, v3)) > 0)return Length(v3);
     81     else return fabs(Cross(v1, v2)) / Length(v1);
     82 }
     83 Point GetlineProjection(Point P, Point A, Point B)
     84 //点P在直线AB上的投影
     85 {
     86     Vector v = B - A;
     87     return A + v *(Dot(v, P-A) / Dot(v,v));
     88 }
     89 bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2)
     90 //判断线段a1a2和b1b2是否规范相交(在端点处相交得用下一个函数特殊判断)
     91 {
     92     double c1 = Cross(a2-a1, b1-a1), c2 = Cross(a2-a1, b2-a1),
     93            c3 = Cross(b2-b1, a1-b1), c4 = Cross(b2-b1, a2-b1);
     94     return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
     95 }
     96 bool OnSegment(Point p, Point a1, Point a2)//在线段上返回1,不在返回0
     97 //判断点P是否在线段a1a2上(不包括端点)
     98 {
     99     return dcmp(Cross(a1-p, a2-p)) == 0 && dcmp(Dot(a1-p, a2-p)) < 0;
    100 }
    101 bool OnSegment2(Point p, Point a1, Point a2)//在线段上返回1,不在返回0
    102 //判断点P是否在线段a1a2上(包括端点)
    103 {
    104     return OnSegment(p, a1, a2) || p == a1 || p == a2;
    105 }

    多边形:

     1 //多边形面积
     2 double PolygonArea(Point* p, int n)
     3 {
     4     double area = 0;
     5     for(int i = 1; i < n - 1; i++)
     6         area += Cross(p[i] - p[0], p[i + 1] - p[0]);
     7     return area / 2;
     8 }
     9 
    10 //点在多边形内判定
    11 int isPointInPolygon(Point p, Point * poly, int n)
    12 {
    13     int wn = 0;
    14     for(int i = 0; i < n; i++)
    15     {
    16         if(OnSegment2(p, poly[i], poly[(i + 1) % n]))return -1;//点在多边形边界上
    17         int k = dcmp(Cross(poly[(i + 1) % n] - poly[i], p - poly[i]));
    18         int d1 = dcmp(poly[i].y - p.y);
    19         int d2 = dcmp(poly[(i + 1) % n].y - p.y);
    20         if(k > 0 && d1 <= 0 && d2 > 0)wn++;
    21         if(k < 0 && d2 <= 0 && d1 > 0)wn--;
    22     }
    23     if(wn != 0)return 1;//内部
    24     return 0;//外部
    25 }
    26 
    27 //凸包:输入点数组p,个数为n,输出点数组为ch,返回输出点个数
    28 //输入不能有重复点,函数执行完输入点顺序被破坏
    29 //如果不希望凸包的边上存在输入点,把两个<=改成<
    30 int ConvexHull(Point* p, int n, Point * ch)
    31 {
    32     sort(p, p + n);
    33     int m = 0;
    34     for(int i = 0; i < n; i++)
    35     {
    36         while(m > 1 && dcmp(Cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2])) <= 0)m--;//可将此处的<=改成<,保证凸包的边上没有点
    37         ch[m++] = p[i];
    38     }
    39     int k = m;
    40     for(int i = n - 2; i >= 0; i--)
    41     {
    42         while(m > k && dcmp(Cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2])) <= 0)m--;
    43         ch[m++] = p[i];
    44     }
    45     if(n > 1)m--;
    46     return m;
    47 }

     

     1 struct Circle
     2 {
     3     Point c;//圆心
     4     double r;//半径
     5     Circle(){}
     6     Circle(Point c, double r):c(c), r(r){}
     7     Point point(double a)//在圆上圆心角为a的点
     8     {
     9         return Point(c.x + cos(a) * r, c.y + sin(a) * r);
    10     }
    11 };
  • 相关阅读:
    电子书下载:Beginning ASP.NET 2.0 AJAX
    电子书下载:C# 4.0 How To
    电子书下载:Pragmatic Unit Testing in C# with NUnit
    7 个最好的.Net开源CMS系统
    电子书下载:Professional ASP.NET 2.0 Server Control and Component Development
    电子书下载:Beginning ASP.NET 2.0 Databases From Novice to Professional
    电子书下载:Professional .NET 2.0 Generics
    蛙蛙推荐:[算法练习]最长不完全匹配子串频率计算
    蛙蛙推荐:F#实现并行排序算法
    蛙蛙推荐:蛙蛙教你发明一种新语言之二代码生成
  • 原文地址:https://www.cnblogs.com/fzl194/p/9338195.html
Copyright © 2011-2022 走看看