POJ3675 Telescope

题目大意

求圆和矩形的面积交

简要题解

我有板子嘿嘿嘿~

  1 #include <cmath>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <cstdlib>
  6 #include <vector>
  7 #include <map>
  8 #include <set>
  9 #include <iostream>
 10 using namespace std;
 11 namespace my_header {
 12 #define pb push_back
 13 #define mp make_pair
 14 #define pir pair<int, int>
 15 #define vec vector<int>
 16 #define pc putchar
 17 #define clr(t) memset(t, 0, sizeof t)
 18 #define pse(t, v) memset(t, v, sizeof t)
 19 #define bl puts("")
 20 #define wn(x) wr(x), bl
 21 #define ws(x) wr(x), pc(' ')
 22     const int INF = 0x3f3f3f3f;
 23     typedef long long LL;
 24     typedef double DB;
 25     inline char gchar() {
 26         char ret = getchar();
 27         for(; (ret == '\n' || ret == '\r' || ret == ' ') && ret != EOF; ret = getchar());
 28         return ret; }
 29     template<class T> inline void fr(T &ret, char c = ' ', int flg = 1) {
 30         for(c = getchar(); (c < '0' || '9' < c) && c != '-'; c = getchar());
 31         if (c == '-') { flg = -1; c = getchar(); }
 32         for(ret = 0; '0' <= c && c <= '9'; c = getchar())
 33             ret = ret * 10 + c - '0';
 34         ret = ret * flg; }
 35     inline int fr() { int t; fr(t); return t; }
 36     template<class T> inline void fr(T&a, T&b) { fr(a), fr(b); }
 37     template<class T> inline void fr(T&a, T&b, T&c) { fr(a), fr(b), fr(c); }
 38     template<class T> inline char wr(T a, int b = 10, bool p = 1) {
 39         return a < 0 ? pc('-'), wr(-a, b, 0) : (a == 0 ? (p ? pc('0') : p) : 
 40             (wr(a/b, b, 0), pc('0' + a % b)));
 41     }
 42     template<class T> inline void wt(T a) { wn(a); }
 43     template<class T> inline void wt(T a, T b) { ws(a), wn(b); }
 44     template<class T> inline void wt(T a, T b, T c) { ws(a), ws(b), wn(c); }
 45     template<class T> inline void wt(T a, T b, T c, T d) { ws(a), ws(b), ws(c), wn(d); }
 46     template<class T> inline T gcd(T a, T b) {
 47         return b == 0 ? a : gcd(b, a % b); }
 48     template<class T> inline T fpw(T b, T i, T _m, T r = 1) {
 49         for(; i; i >>= 1, b = b * b % _m)
 50             if(i & 1) r = r * b % _m;
 51         return r; }
 52 };
 53 using namespace my_header;
 54 
 55 const DB PI = 3.1415926535897932384626;
 56 const DB EPS = 1e-6;
 57 int sgn(DB x) {
 58     return x < -EPS ? -1 : EPS < x;
 59 }
 60 
 61 #define Vector Point
 62 struct Point {
 63     DB x, y;
 64     Point() {}
 65     Point(DB x, DB y):x(x), y(y) {}
 66     Vector operator + (Vector);
 67     Vector operator - (Vector);
 68     Vector operator * (DB);
 69     Vector operator / (DB);
 70     DB getCross(Vector);
 71     DB getDot(Vector);
 72     DB getLength();
 73     DB getAngle(Vector);
 74     Vector getNorm();
 75     Vector Rotate(DB);
 76 };
 77 Vector Vector::operator + (Vector b) {
 78     return Vector(x + b.x, y + b.y);
 79 }
 80 Vector Vector::operator - (Vector b) {
 81     return Vector(x - b.x, y - b.y);
 82 }
 83 Vector Vector::operator * (DB b) {
 84     return Vector(x * b, y * b);
 85 }
 86 Vector Vector::operator / (DB b) {
 87     return Vector(x / b, y / b);
 88 }
 89 DB Vector::getCross(Vector b) {
 90     return x * b.y - y * b.x;
 91 }
 92 DB Vector::getDot(Vector b) {
 93     return x * b.x + y * b.y;
 94 }
 95 DB Vector::getLength() {
 96     return sqrt(this->getDot(*this));
 97 }
 98 Vector Vector::Rotate(DB ang) {
 99     DB c = cos(ang), s = sin(ang);
100     return Vector(c * x - s * y, s * x + c * y);
101 }
102 Vector Vector::getNorm() {
103     DB l = this->getLength();
104     return Vector(x / l, y / l);
105 }
106 DB Vector::getAngle(Vector b) {
107     DB t = atan2(b.y, b.x) - atan2(y, x);
108     while (t > PI)
109         t -= 2 * PI;
110     while (t < -PI)
111         t += 2 * PI;
112     return t;
113 }
114 
115 struct Circle {
116     Point o;
117     DB r;
118     DB getSectorArea(DB);
119     vector<Point> getSegmentIntersection(Point, Point);
120 };
121 
122 DB getSegmentCirlcleProjectionArea(Circle, Point, Point);
123 DB getTriangleCircleIntersectionArea(Circle, Point, Point, Point);
124 bool onSegment(Point, Point, Point);
125 
126 
127 DB getSegmentCirlcleProjectionArea(Circle C, Point a, Point b) {
128     vector<Point> t = C.getSegmentIntersection(a, b);
129     if (t.size() == 0) {
130         if ((a - C.o).getLength() < C.r + EPS && (b - C.o).getLength() < C.r + EPS)
131             return (a - C.o).getCross(b - C.o) / 2;
132         return C.getSectorArea((a - C.o).getAngle(b - C.o));
133     }
134     if (t.size() == 1) {
135         Point c = t.at(0);
136         if ((a - C.o).getLength() <= C.r) {
137             return C.getSectorArea((c - C.o).getAngle(b - C.o)) + (a - C.o).getCross(c - C.o) / 2;
138         }
139         else {
140             return C.getSectorArea((a - C.o).getAngle(c - C.o)) + (c - C.o).getCross(b - C.o) / 2;
141         }
142     }
143     return C.getSectorArea((a - C.o).getAngle(t[0] - C.o)) + (t[0] - C.o).getCross(t[1] - C.o) / 2 + C.getSectorArea((t[1] - C.o).getAngle(b - C.o));
144 }
145 
146 DB getTriangleCircleIntersectionArea(Circle C, Point a, Point b, Point c) {
147     DB res = 0;
148     res += getSegmentCirlcleProjectionArea(C, a, b);
149     res += getSegmentCirlcleProjectionArea(C, b, c);
150     res += getSegmentCirlcleProjectionArea(C, c, a);
151     return fabs(res);
152 }
153 
154 
155 
156 bool onSegment(Point a, Point b, Point c) {
157     return sgn((c - a).getDot(b - a)) > 0 && sgn((c - b).getDot(a - b)) > 0;
158 }
159 
160 DB Circle::getSectorArea(DB ang) {
161     return ang * r * r / 2;
162 }
163 vector<Point> Circle::getSegmentIntersection(Point a, Point b) {
164     vector<Point> res;
165     Point p = a + (b - a).getNorm() * (b - a).getDot(o - a) / (b - a).getLength();
166     if ((p - o).getLength() >= r)
167         return res;
168     DB d = sqrt(r * r - (p - o).getDot(p - o));
169     Vector tmp = (b - a).getNorm() * d;
170     if (onSegment(a, b, p - tmp))
171         res.push_back(p - tmp);
172     if (onSegment(a, b, p + tmp))
173         res.push_back(p + tmp);
174     return res;
175 }
176 
177 int main() {
178 #ifdef lol
179     freopen("3675.in", "r", stdin);
180     freopen("3675.out", "w", stdout);
181 #endif
182 
183     Circle C;
184     C.o = Point(0, 0);
185     vector<Point> pt;
186     int n;
187     while (cin >> C.r) {
188         cin >> n;
189         pt.clear();
190         for (int i = 0; i < n; ++i) {
191             DB x, y;
192             cin >> x >> y;
193             pt.push_back(Point(x, y));
194         }
195         DB ans = 0;
196         for (int i = 1; i < n; ++i)
197             ans += getSegmentCirlcleProjectionArea(C, pt[i - 1], pt[i]);
198         ans += getSegmentCirlcleProjectionArea(C, pt[n - 1], pt[0]);
199         printf("%.2lf\n", fabs(ans));
200     }
201 
202 
203     return 0;
204 }

 

posted @ 2017-02-20 19:48  ichneumon  阅读(153)  评论(0编辑  收藏  举报