标签:clu nbsp max 技术分享 ret inf struct cti img
1 /************************************************************************* 2 > File Name: board.cpp 3 > Author: yijiull 4 > Mail: 1147161372@qq.com 5 > Created Time: 2017年09月23日 星期六 10时50分19秒 6 ************************************************************************/ 7 #include <iostream> 8 #include <cstring> 9 #include <cstdio> 10 #include <bits/stdc++.h> 11 using namespace std; 12 #define FP freopen("in.txt", "r", stdin) 13 const double eps = 1e-12; 14 const double pi = acos(-1.0); 15 const int inf = 0x3f3f3f3f; 16 struct Point { 17 double x,y; 18 Point (double x = 0, double y = 0) : x(x), y(y) {} 19 }; 20 typedef Point Vector; 21 Vector operator + (Vector a, Vector b) { 22 return Vector (a.x + b.x, a.y + b.y); 23 } 24 Vector operator * (Vector a, double s) { 25 return Vector (a.x * s, a.y * s); 26 } 27 Vector operator / (Vector a, double p) { 28 return Vector (a.x / p, a.y / p); 29 } 30 Vector operator - (Point a, Point b) { 31 return Vector (a.x - b.x, a.y - b.y); 32 } 33 bool operator < (Point a, Point b) { 34 return a.x < b.x || (a.x == b.x && a.y < b.y); 35 } 36 int dcmp (double x) { 37 if(fabs(x) < eps) return 0; 38 return x < 0 ? -1 : 1; 39 } 40 bool operator == (const Point &a, const Point &b) { 41 return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0; 42 } 43 double Dot(Vector a, Vector b) { 44 return a.x * b.x + a.y * b.y; 45 } 46 double Length (Vector a) { 47 return sqrt(Dot(a, a)); 48 } 49 double Angle (Vector a) { 50 return atan2(a.y, a.x); 51 } 52 double Cross (Vector a, Vector b) { 53 return a.x * b.y - a.y * b.x; 54 } 55 //判断两线段是否规范相交 56 bool SegmentProperIntersection(Point a1, Point b1, Point a2, Point b2) { 57 double c1 = Cross(b1 - a1, a2 - a1), c2 = Cross(b1 - a1, b2 - a1), 58 c3 = Cross(b2 - a2, a1 - a2), c4 = Cross(b2 - a2, b1 - a2); 59 return dcmp(c1)*dcmp(c2) < 0 && dcmp(c3)*dcmp(4) < 0; 60 } 61 //判断点是否在线段上(即∠apb等于π) 62 bool OnSegment(Point p, Point a, Point b) { 63 return dcmp(Cross(a - p, b - p)) == 0 && dcmp(Dot(a - p, b - p)) < 0; 64 } 65 //两直线交点 66 Point GetLineIntersection (Point p, Vector v, Point q, Vector w) { 67 Vector u = p - q; 68 double t1 = Cross(w, u) / Cross(v, w); 69 double t2 = Cross(v, u) / Cross(v, w); 70 return p + v * t1; // return q + w * t2; 71 } 72 const int maxn = 110; 73 Point p[maxn], res[maxn], temp[maxn]; 74 double ang[maxn], s; 75 int cnt; 76 77 void add(Point a, Point b) { 78 temp[cnt] = a; 79 ang[cnt] = Angle(a - b) - s; 80 while(dcmp(ang[cnt]) <= 0) ang[cnt] += 2*pi; 81 cnt++; 82 } 83 84 int main(){ 85 int n; 86 FP; 87 while(scanf("%d", &n) != EOF) { 88 int fg = 0; 89 for(int i = 0; i < n; i++) { 90 scanf("%lf %lf", &p[i].x, &p[i].y); 91 if(p[i] < p[fg]) fg = i; 92 } 93 res[0] = p[fg]; 94 int num = 1; 95 s = -pi; 96 while (1) { 97 cnt = 0; 98 for (int i = 0; i < n; i++) { 99 if (res[num - 1] == p[i]) { 100 add(p[(i + 1) % n], res[num - 1]); 101 add(p[(i + n - 1) % n], res[num - 1]); 102 break; 103 } 104 } 105 for (int i = 0; i < n; i++) { 106 if (OnSegment(res[num - 1], p[i], p[(i + 1) % n])) { 107 add(p[(i + 1) % n], res[num - 1]); 108 add(p[i], res[num - 1]); 109 } 110 } 111 int id = 0; 112 for (int i = 0; i < cnt; i++) 113 if (ang[i] < ang[id]) 114 id = i; 115 double minlen = 1e9; 116 Point RP = temp[id], its; 117 for (int i = 0; i < n; i++) { 118 if (SegmentProperIntersection(temp[id], res[num - 1], p[i], p[(i + 1) % n])) { 119 its = GetLineIntersection(temp[id], temp[id] - res[num - 1], p[i], p[i] - p[(i + 1) % n]); 120 if (Length(its - res[num - 1]) < minlen) { 121 minlen = Length(its - res[num - 1]); 122 RP = its; 123 } 124 } 125 } 126 res[num] = RP; 127 s = atan2(res[num - 1].y - res[num].y, res[num - 1].x - res[num].x); 128 num++; 129 if (res[num - 1] == res[0]) 130 break; 131 } 132 printf("%d\n", num - 1); 133 for (int i = 0; i < num - 1; i++) 134 printf("%.4lf %.4lf\n", res[i].x, res[i].y); 135 } 136 return 0; 137 }
标签:clu nbsp max 技术分享 ret inf struct cti img
原文地址:http://www.cnblogs.com/yijiull/p/7580641.html