1. 程式人生 > >計算幾何模板

計算幾何模板

code project 希望 返回 三角形 polygon 重復 cetos fab

基礎模板

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

計算幾何模板