/* Problem URL: https://codeforces.com/gym/104871/problem/G */ #include #include #include using namespace std; using namespace __gnu_pbds; template > using ordered_set = tree; #define V vector #define rmin(a, b) a = min(a, b) #define rmax(a, b) a = max(a, b) #define rep(i, lim) for (int i = 0; i < (lim); i++) #define nrep(i, s, lim) for (int i = s; i < (lim); i++) #define repv(i, v) for (auto &i : (v)) #define fillv(v) for (auto &itr_ : (v)) { cin >> itr_; } #define sortv(v) sort(v.begin(), v.end()) #define all(v) (v).begin(), (v).end() using vi = vector; using vvi = vector; using vvvi = vector; using vvvvi = vector; using ll = long long; using vl = vector; using vvl = vector; using vvvl = vector; using vvvvl = vector; template auto operator<<(ostream &os, const vector &vec)->ostream& { os << vec[0]; for (size_t i = 1; i < vec.size(); i++) { os << ' ' << vec[i]; } os << '\n'; return os; } template auto operator>>(istream &is, vector &vec)->istream& { for (auto &i : vec) { is >> i; } return is; } template auto operator<<(ostream &os, const vector> &vec)->ostream& { for (auto &i : vec) { os << i[0]; for (size_t j = 1; j < i.size(); j++) { os << ' ' << i[j]; } os << '\n'; } return os; } template auto operator>>(istream &is, vector> &vec)->istream& { for (auto &i : vec) { for (auto &j : i) { is >> j; } } return is; } using ld = long double; ld EPS = 1e-16L; bool eq(ld a, ld b) { return abs(a - b) <= EPS; } struct pt { ld x, y; pt(ld x = 0, ld y = 0): x(x), y(y) {} ld operator^(const pt p) const { return x*p.y - y*p.x; } pt operator-(const pt p) const { return {x - p.x, y - p.y}; } ld operator*(const pt p) const { return x*p.x + y*p.y; } friend istream& operator >> (istream& in, pt &p) { return in >> p.x >> p.y; } }; ld dist(pt p, pt q) { return hypot(p.y - q.y, p.x - q.x); } ld sarea(pt p, pt q, pt r) { return ((q-p)^(r-q)) / 2; } struct line { pt p, q; line() {} line (pt p, pt q): p(p), q(q) {} }; bool ccw(pt p, pt q, pt r) { return sarea(p, q, r) > EPS; } ld disttoline(pt p, line r) { return 2 * abs(sarea(p, r.p, r.q)) / dist(r.p, r.q); } bool isinseg(pt p, line r) { pt a = r.p - p, b = r.q - p; return eq((a^b), 0) and (a * b) < EPS; } bool interseg(line r, line s) { if (isinseg(r.p, s) or isinseg(r.q, s) or isinseg(s.p, r) or isinseg(s.q, r)) { return true; } return ccw(r.p, r.q, s.p) != ccw(r.p, r.q, s.q) and ccw(s.p, s.q, r.p) != ccw(s.p, s.q, r.q); } ld disttoseg(pt p, line r) { if ((r.q - r.p) * (p - r.p) < 0) { return dist(r.p, p); } if ((r.p - r.q) * (p - r.q) < 0) { return dist(r.q, p); } return disttoline(p, r); } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t; cin >> t; while (t--) { pt a, b; pt cir; ld r; cin >> a >> b >> cir >> r; if (eq(a.x, b.x) && eq(a.y, b.y)) { ld dista = dist(a, cir); if (dista <= r) { cout << "0\n"; continue; } dista -= r; cout << setprecision(12) << (dista - r) * 2 << '\n'; continue; } ld distret = disttoseg(cir, line(a, b)); cout << distret << '\n'; if (distret <= r) { cout << setprecision(12) << dist(a, b) << '\n'; continue; } a.x -= cir.x; a.y -= cir.y; b.x -= cir.x; b.y -= cir.y; ld low = -r; ld high = r; ld ans = 1e18; ld eps = 1e-9; while (high - low >= eps) { ld third = (high - low) / 3; ld mid1 = low + third; ld mid2 = high - third; auto getans = [&](ld mid) { ld one = (a.x - mid); ld two = (a.y - sqrt(r * r - mid * mid)); ld ac = sqrt(one * one + two * two); one = (b.x - mid); two = (b.y - sqrt(r * r - mid * mid)); ac += sqrt(one * one + two * two); return ac; }; ld ans1 = getans(mid1); ld ans2 = getans(mid2); if (ans1 <= ans2) { high = mid2; ans = ans1; continue; } low = mid1; ans = ans2; } low = -r; high = r; while (high - low >= eps) { ld third = (high - low) / 3; ld mid1 = low + third; ld mid2 = high - third; auto getans = [&](ld mid) { ld one = (a.x - mid); ld two = (a.y + sqrt(r * r - mid * mid)); ld ac = sqrt(one * one + two * two); one = (b.x - mid); two = (b.y + sqrt(r * r - mid * mid)); ac += sqrt(one * one + two * two); return ac; }; ld ans1 = getans(mid1); ld ans2 = getans(mid2); if (ans1 <= ans2) { high = mid2; ans = ans1; continue; } low = mid1; ans = ans2; } cout << setprecision(12) << ans << '\n'; } }