Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define ll long long
- #define db long double
- #define x first
- #define y second
- #define mp make_pair
- #define pb push_back
- #define all(a) a.begin(), a.end()
- using namespace std;
- const double EPS = 1e-8;
- struct TVector {
- double x, y;
- };
- TVector operator+(TVector a, TVector b) {
- return {a.x + b.x, a.y + b.y};
- }
- TVector operator-(TVector a, TVector b) {
- return {a.x - b.x, a.y - b.y};
- }
- double operator*(TVector a, TVector b) {
- return a.x * b.y - a.y * b.x;
- }
- double operator%(TVector a, TVector b) {
- return a.x * b.x + a.y * b.y;
- }
- TVector operator*(TVector a, double k) {
- return {a.x * k, a.y * k};
- }
- double len(TVector a) {
- return sqrt(a % a);
- }
- TVector norm(TVector a) {
- return a * (1. / len(a));
- }
- struct TLine {
- double a, b, c;
- TLine(TVector A, TVector B) {
- a = A.y - B.y;
- b = B.x - A.x;
- c = A.y * B.x - B.y * A.x;
- }
- TLine(double a, double b, double c) : a(a), b(b), c(c) {}
- double dist(TVector A) {
- double top = abs(a * A.x + b * A.y - c);
- double bot = len({a, b});
- return top / bot;
- }
- };
- vector <TVector> intersection(TLine l, TVector O, double r) {
- double d = l.dist(O);
- if (d > r + EPS) {
- return {};
- }
- TVector v = {-l.a, -l.b};
- TVector A = O + norm(v) * d;
- //cout << O.x << " " << r << " " << A.x << " " << A.y << endl;
- if (abs(r - d) < EPS) {
- return {A};
- }
- double len = sqrt(r * r - d * d);
- TVector u = norm({l.b, -l.a});
- return {A + u * len, A - u * len};
- }
- vector <TVector> intersection(TVector O1, double r1, TVector O2, double r2) {
- double wasx = O1.x, wasy = O1.y;
- O2.x -= O1.x;
- O2.y -= O1.y;
- O1.x = 0;
- O1.y = 0;
- double a = 2 * O2.x;
- double b = 2 * O2.y;
- double c = (r1 * r1 - r2 * r2) + O2.x * O2.x + O2.y * O2.y;
- if (abs(a) < EPS && abs(b) < EPS) {
- return {};
- }
- TLine l(a, b, c);
- auto res = intersection(l, O2, r2);
- for (auto &t : res) {
- //cout << t.x << " " << t.y << "\n";
- t.x += wasx;
- t.y += wasy;
- }
- return res;
- }
- vector<db> its(db x, db y, db r, db crd){
- if (fabsl(x-crd) - EPS > r) return {};
- db kek = r*r-(x*crd)*(x*crd);
- kek = max(kek, (db) 0);
- kek = sqrt(kek);
- return {y-kek, y+kek};
- }
- vector<db> ginter(int x, int y, int r, int R, db crd){
- vector<db> a = its(x, y, r, crd);
- vector<db> b = its(x, y, R, crd);
- for (int i=0; i < b.size(); ++i) a.push_back(b[i]);
- sort(a.begin(), a.end());
- return a;
- }
- db func(db x){
- return sqrt(1. - x*x) * x + asin(x);
- }
- db integrate(db x, db y, db r, db xl, db xr, bool high){
- if (high){
- xl -= x, xr -= x;
- xl /= r, xr /= r;
- db delta = func(xr) - func(xl);
- delta *= (r*r);
- delta += (xr-xl) * y;
- return delta;
- }
- else{
- xl -= x, xr -= x;
- xl /= r, xr /= r;
- db delta = func(xr) - func(xl);
- delta *= (r*r);
- delta *= (-1);
- delta += (xr-xl) * y;
- return delta;
- }
- }
- void solve(){
- int r, R, xa, ya, xb, yb;
- cin >> r >> R >> xa >> ya >> xb >> yb;
- xa += 200, ya += 200, xb += 200, yb += 200;
- int lft = max(xa-R, xb-R);
- int rgt = min(xa+R, xb+R);
- if (lft >= rgt){
- cout << 0 << "\n";
- return;
- }
- vector<db> arr = {lft, rgt};
- auto kek = intersection({xa, ya}, r, {xb, yb}, r);
- for (int i=0; i < kek.size(); ++i){
- db Q = kek[i].x;
- arr.push_back(Q);
- }
- kek = intersection({xa, ya}, R, {xb, yb}, r);
- for (int i=0; i < kek.size(); ++i){
- db Q = kek[i].x;
- arr.push_back(Q);
- }
- kek = intersection({xa, ya}, R, {xb, yb}, R);
- for (int i=0; i < kek.size(); ++i){
- db Q = kek[i].x;
- arr.push_back(Q);
- }
- kek = intersection({xa, ya}, r, {xb, yb}, R);
- for (int i=0; i < kek.size(); ++i){
- db Q = kek[i].x;
- arr.push_back(Q);
- }
- sort(arr.begin(), arr.end());
- db ans = 0;
- for (int i=0; i + 1 < arr.size(); ++i){
- db F = arr[i], Q = arr[i+1];
- if (abs(Q-F) < EPS){
- continue;
- }
- db x = (Q+F)/2;
- vector<db> ainter = ginter(xa, ya, r, R, x);
- vector<db> binter = ginter(xb, yb, r, R, x);
- vector<pair<db, int> > res;
- for (int j=0; j < ainter.size(); ++j) res.push_back({ainter[j], 1});
- for (int j=0; j < binter.size(); ++j) res.push_back({binter[j], 2});
- sort(res.begin(), res.end());
- int A = 0, B = 0;
- for (int j=0; j + 1 < res.size(); ++j){
- if (res[j].second==1) A++;
- else B++;
- if (A%2 != 0 && B % 2 != 0){
- if (res[j].second == 1){
- if (A==1) ans += integrate(xa, ya, R, A, B, 1);
- else ans += integrate(xa, ya, r, A, B, 0);
- }
- else{
- if (B==1) ans += integrate(xb, yb, R, A, B, 1);
- else ans += integrate(xb, yb, r, A, B, 0);
- }
- }
- else{
- if (res[j+1].second == 1){
- if (A==1) ans -= integrate(xa, ya, r, A, B, 1);
- else ans -= integrate(xa, ya, R, A, B, 0);
- }
- else{
- if (B==1) ans -= integrate(xb, yb, r, A, B, 1);
- else ans -= integrate(xb, yb, R, A, B, 0);
- }
- }
- }
- }
- cout.precision(10);
- cout << ans << "\n";
- }
- int main(){
- #ifdef LOCAL
- freopen("I_input.txt", "r", stdin);
- //freopen("I_output.txt", "w", stdout);
- #endif
- ios_base::sync_with_stdio(0);
- cin.tie(0);
- cout.precision(20);
- int t;
- cin >> t;
- for (int i=0; i < t; ++i) solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement