1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| #include <iostream> #include <cmath> #include <iomanip>
using std::cin;
const double EPS = 1e-11;
struct circle { double x, y, r; double D, E, F; };
double t1, t2; double disABS, disACS, disBCS; double disAB, disAC, disBC;
bool Check(const double& mid, circle A, circle B, circle C); bool CheckCircle(circle A, circle B, circle C); double GetDisS(const circle& X, const circle& Y);
int main() { circle A, B, C;
cin >> t1 >> t2; cin >> A.x >> A.y; cin >> B.x >> B.y; cin >> C.x >> C.y;
disABS = GetDisS(A, B), disAB = sqrt(disABS); disACS = GetDisS(A, C), disAC = sqrt(disACS); disBCS = GetDisS(B, C), disBC = sqrt(disBCS);
if ((disAC + disBC) - (disAB + t2) <= EPS) { std::cout << std::fixed << std::setprecision(4) << std::min(disAC + disBC + t1, disAB + t2) << std::endl; } else { double l = 0, r = disAB + t2;
while (r - l > EPS) { double mid = (l + r) / 2.0; if (Check(mid, A, B, C)) { l = mid; } else { r = mid; } }
std::cout << std::fixed << std::setprecision(4) << l << std::endl; }
return 0; }
bool Check(const double& mid, circle A, circle B, circle C) { A.r = mid, B.r = t2 + disAB - mid, C.r = t1 + disAC - mid; bool flag = false; flag |= CheckCircle(A, B, C); flag |= CheckCircle(B, C, A); flag |= CheckCircle(A, C, B); return flag; }
bool CheckCircle(circle A, circle B, circle C) { double disABS = GetDisS(A, B), disAB = sqrt(disABS); double disACS = GetDisS(A, C), disAC = sqrt(disACS); double disBCS = GetDisS(B, C), disBC = sqrt(disBCS);
if (A.r + B.r - disAB <= -EPS) { return false; } else if (A.r + disAB - B.r <= EPS) { return disAC - (A.r + C.r) <= EPS; } else if (B.r + disAB - A.r <= EPS) { return disBC - (B.r + C.r) <= EPS; } else { A.D = -2.0 * A.x, A.E = -2.0 * A.y, A.F = pow(A.x, 2) + pow(A.y, 2) - pow(A.r, 2); B.D = -2.0 * B.x, B.E = -2.0 * B.y, B.F = pow(B.x, 2) + pow(B.y, 2) - pow(B.r, 2); double D = A.D - B.D, E = A.E - B.E, F = A.F - B.F;
circle M, N;
if (fabs(E) > EPS) { D = -D / E, F = -F / E; double a, b, c; a = 1 + pow(D, 2); b = A.D + 2.0 * D * F + A.E * D; c = pow(F, 2) + A.E * F + A.F; M.x = (-b + sqrt(fabs(pow(b, 2) - 4.0 * a * c))) * 0.5 / a; M.y = D * M.x + F; N.x = (-b - sqrt(fabs(pow(b, 2) - 4.0 * a * c))) * 0.5 / a; N.y = D * N.x + F; } else { M.x = N.x = -F / D; M.y = sqrt(fabs(pow(A.r, 2) - pow(A.x - M.x, 2))) + A.y; N.y = sqrt(fabs(pow(A.r, 2) - pow(A.x - M.x, 2))) - A.y; } double disCM = sqrt(GetDisS(C, M)); double disCN = sqrt(GetDisS(C, N));
return std::min(disCM, disCN) - C.r <= EPS; } }
double GetDisS(const circle& X, const circle& Y) { return pow(X.x - Y.x, 2) + pow(X.y - Y.y, 2); }
|