计算几何:直线与圆的交点 (5252: Triangle to Hexagon)

http://exam.upc.edu.cn/problem.php?id=5252

斜截式表示直线方程


求直线与直线交点,直线与圆交点

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 const long double EPS = 0.0000001;
  4 
  5 // a == b return 0
  6 // a > b return 1
  7 // a < b return -1
  8 inline int cmp(long double a, long double b) {
  9     if(abs(a - b) < EPS) return 0;
 10     return a > b? 1: -1;
 11 }
 12 struct point {
 13     long double x, y;
 14     void print() {
 15         printf(" (%.4Lf, %.4Lf)\n", x, y);
 16     }
 17 };
 18 struct line {
 19     long double k, b;
 20     bool isk = true;
 21     line() {}
 22     line(long double x1, long double y1, long double x2, long double y2) {
 23         if(!cmp(x1, x2)) {
 24             isk = false;
 25             b = x1;
 26         } else {
 27             isk = true;
 28             k = (y1 - y2) / (x1 - x2);
 29             b = y1 - k * x1;
 30         }
 31     }
 32     line(point a, point b) {
 33         *this = line(a.x, a.y, b.x, b.y);
 34     }
 35     void print() {
 36         printf(" k = %.4Lf, b = %.4Lf\n", k, b);
 37     }
 38 };
 39 struct circle {
 40     point o;
 41     long double r;
 42     void print() {
 43         printf(" center:(%.4Lf, %.4Lf) rad: %.4Lf\n", o.x, o.y, r);
 44     }
 45 };
 46 inline long double dist (point a, point b) {
 47     return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
 48 }
 49 circle getWjc(point a, point b, point c) {
 50     long double a1 = b.x - a.x, b1 = b.y - a.y, c1 = (a1*a1 + b1*b1)/2;
 51     long double a2 = c.x - a.x, b2 = c.y - a.y, c2 = (a2*a2 + b2*b2)/2;
 52     long double d = a1 * b2 - a2 * b1;
 53     circle cir;
 54     cir.o.x = a.x + (c1*b2 - c2*b1)/d;
 55     cir.o.y = a.y + (a1*c2 - a2*c1)/d;
 56     cir.r = dist(cir.o, a);
 57     return cir;
 58 }
 59 circle getNqc(point a, point b, point c) {
 60     long double C = dist(a, b);
 61     long double B = dist(a, c);
 62     long double A = dist(b, c);
 63     circle cir;
 64     cir.o.x = (A*a.x + B*b.x + C*c.x) / (A + B + C);
 65     cir.o.y = (A*a.y + B*b.y + C*c.y) / (A + B + C);
 66     cir.r = sqrt((A + B - C)*(A - B + C)*(-A + B + C) / (A + B + C)) / 2;
 67     return cir;
 68 }
 69 pair<point, point> getPoint(circle cir, line l) {
 70     pair<point, point> ans;
 71     if(l.isk) {
 72         long double x0 = cir.o.x;
 73         long double y0 = cir.o.y;
 74         long double a = (1 + l.k * l.k);
 75         long double b = (2*l.k*(l.b-y0)-2*x0);
 76         long double c = (x0*x0+(l.b-y0)*(l.b-y0)-cir.r*cir.r);
 77         long double deta = b * b - 4 * a * c;
 78         long double x1 = ( - b - sqrt(deta)) / (2 * a);
 79         long double x2 = ( - b + sqrt(deta)) / (2 * a);
 80         long double y1 = l.k*x1+l.b;
 81         long double y2 = l.k*x2+l.b;
 82         ans.first.x = x1;
 83         ans.first.y = y1;
 84         ans.second.x = x2;
 85         ans.second.y = y2;
 86     } else {
 87         long double x0 = cir.o.x;
 88         long double y0 = cir.o.y;
 89         long double y1 = y0 - sqrt(cir.r*cir.r - (l.b - x0) * (l.b - x0));
 90         long double y2 = y0 + sqrt(cir.r*cir.r - (l.b - x0) * (l.b - x0));
 91         ans.first.x = l.b;
 92         ans.first.y = y1;
 93         ans.second.x = l.b;
 94         ans.second.y = y2;
 95     }
 96     return ans;
 97 }
 98 point getPoint(line l1, line l2) {
 99     point ans;
100     if( ((!l1.isk) && (!l2.isk)) || (l1.isk && l2.isk && !cmp(l1.k, l2.k)) ) {
101         cerr << "RONG!!!!" << endl; exit(-1);
102     } else {
103         if(!l2.isk) swap(l1, l2);
104         if(l1.isk) {
105             long double b1 = l1.b;
106             long double b2 = l2.b;
107             long double k1 = l1.k;
108             long double k2 = l2.k;
109             long double x = (b2 - b1) / (k1 - k2);
110             long double y = k1*x+b1;
111             ans.x = x;
112             ans.y = y;
113         } else {
114             long double x = l1.b;
115             long double y = l2.k * x + l2.b;
116             ans.x = x;
117             ans.y = y;
118         }
119     }
120     return ans;
121 }
122 point myGetPoint(circle cir, line l, point p) {
123     pair<point, point> points = getPoint(cir, l);
124     long double d1 = dist(points.first, p);
125     long double d2 = dist(points.second, p);
126     if(d1 > d2) return points.first;
127     else return points.second;
128 }
129 int main()
130 {
131     //freopen("in.txt", "r", stdin);
132     ios::sync_with_stdio(false);
133     int p; cin >> p;
134     while(p--) {
135         int k; cin >> k; cout << k << ' ';
136         long double bx, cx, cy;  cin >> bx >> cx >> cy;
137         point A, B, C;
138         A.x = 0; A.y = 0;
139         B.x = bx; B.y = 0;
140         C.x = cx; C.y = cy;
141         circle nqy = getNqc(A, B, C); //nqy.print();
142         circle wjy = getWjc(A, B, C); //wjy.print();
143         point I = nqy.o;
144         line CP(C, I);
145         line AM(A, I);
146         line BN(B, I);
147         point P = myGetPoint(wjy, CP, C);
148         point M = myGetPoint(wjy, AM, A);
149         point N = myGetPoint(wjy, BN, B);
150         line PN(P, N);
151         line NM(N, M);
152         line MP(M, P);
153         line AB(A, B);
154         line BC(B, C);
155         line CA(C, A);
156         point E = getPoint(PN, AB);
157         point F = getPoint(CA, PN);
158         point G = getPoint(NM, CA);
159         point H = getPoint(NM, BC);
160         point J = getPoint(BC, MP);
161         point K = getPoint(AB, MP);
162         cout.flags(ios::fixed);
163         cout.precision(4);
164         cout << dist(E, F) << ' ';
165         cout << dist(F, G) << ' ';
166         cout << dist(G, H) << ' ';
167         cout << dist(H, J) << ' ';
168         cout << dist(J, K) << ' ';
169         cout << dist(K, E) << endl;
170     }
171     return 0;
172 }
173  

猜你喜欢

转载自www.cnblogs.com/upc201713/p/8978833.html