#include <cstdio> #include <cmath> #include <algorithm>
using namespace std;
#define MAXN 100011
template <typename T> T sq(T x) { return x * x; }
const double eps = 1e-8, pi = acos(-1.0); int sgn(double x) { return x < -eps ? -1 : (x > eps ? 1 : 0); }
struct VEC { double x, y; bool operator == (const VEC& b) const { return sgn(x - b.x) == 0 && sgn(y - b.y) == 0; } bool operator < (const VEC& b) const { return sgn(y - b.y) == 0 ? sgn(x - b.x) < 0 : y < b.y; }
VEC operator - (const VEC& b) const { return VEC{x - b.x, y - b.y}; } VEC operator + (const VEC& b) const { return VEC{x + b.x, y + b.y}; }
double len() const { return hypot(x, y); } double dist(const VEC& b) const { return (*this - b).len(); }
double len2() const { return sq(x) + sq(y); } double dist2(const VEC& b) const { return (*this - b).len2(); }
VEC operator * (double k) const { return VEC{x * k, y * k}; } VEC trunc(double l) const { double ori = len(); if (!sgn(ori)) return *this; return *this * (l / ori); }
VEC operator / (double k) const { return VEC{x / k, y / k}; } VEC norm() const { return *this / len(); }
double operator ^ (const VEC& b) const { return x * b.y - y * b.x; } double operator * (const VEC& b) const { return x * b.x + y * b.y; } double rad_di(const VEC& b) const { return atan2(*this ^ b, *this * b); } double rad(const VEC& b) const { return fabs(rad_di(b)); }
VEC rotleft() const { return VEC{-y, x}; } VEC rotright() const { return VEC{y, -x}; } VEC rot(double a) const { double c = cos(a), s = sin(a); return VEC{x * c - y * s, x * s + y * c}; }
double slope() const { double ans = atan2(y, x); if (sgn(ans) < 0) ans += pi; else if (sgn(ans - pi) == 0) ans -= pi; return ans; }
double cross(const VEC& p1, const VEC& p2) const { return (p1 - *this) ^ (p2 - *this); }
int relation(const VEC& b) const { return sgn(b ^ *this); }
VEC operator - () const { return VEC{-x, -y}; } bool SameDi(const VEC& b) const { return sgn(x) == sgn(b.x) && sgn(y) == sgn(b.y); }
void input() { scanf("%lf%lf", &x, &y); } };
struct LINE { VEC s, v; LINE() {} LINE(const VEC& _s, const VEC& _v) : s(_s), v(_v) {} void set(const VEC& _s, double a) { s = _s; v = {cos(a), sin(a)}; } void set(double a, double b, double c) { v = {b, -a}; s = fabs(a) > fabs(b) ? VEC{-c / a, 0} : VEC{0, -c / b}; }
int relation(const VEC& p) const { return sgn((p - s) ^ v); } int relation(const LINE& b) const { if (v.relation(b.v) == 0) return b.relation(s) == 0; return 2; }
VEC CrossPoint(const LINE& b) const { double t = ((b.s - s) ^ b.v) / (v ^ b.v); return s + v * t; }
double dist_di(const VEC& p) const { return (v ^ (p - s)) / v.len(); } double dist(const VEC& p) const { return fabs(dist_di(p)); }
VEC projection(const VEC& p) const { VEC v1 = v.norm(); return v1 * ((p - s) * v1) + s; } VEC symmetry(const VEC& p) const { VEC p0 = projection(p); return p0 * 2 - p; }
void SetAngularBisector(const VEC& a, const VEC& b, const VEC& c) { set(a, (atan2(b.y - a.y, b.x - a.x) + atan2(c.y - a.y, c.x - a.x)) / 2); } };
struct SEG : LINE { VEC e; SEG() {} SEG(const VEC& _s, const VEC& _e) : e(_e), LINE(_s, _e - _s) {}
bool exclusive_between(const VEC& p) const { return sgn((p - s) * (p - e)) < 0; }
bool between(const VEC& p) const { return sgn((p - s) * (p - e)) <= 0; } bool OnSeg(const VEC& p) const { return sgn((p - s) ^ v) == 0 && between(p); } int relation(const SEG& b) const { int d1 = sgn(v ^ (b.s - s)); int d2 = sgn(v ^ (b.e - s)); int d3 = sgn(b.v ^ (s - b.s)); int d4 = sgn(b.v ^ (e - b.s)); if ((d1 ^ d2) == -2 && (d3 ^ d4) == -2) return 2; else return (d1 == 0 && between(b.s)) || (d2 == 0 && between(b.e)) || (d3 == 0 && b.between(s)) || (d4 == 0 && b.between(e)); } int relation(const LINE& b) const { int d1 = sgn(b.v ^ (s - b.s)); int d2 = sgn(b.v ^ (e - b.s)); if ((d1 ^ d2) == -2) return 2; else return d1 == 0 || d2 == 0; } double dist(const VEC& p) const { if (sgn((p - s) * v) < 0 || sgn((p - e) * v) > 0) return min(p.dist(s), p.dist(e)); return LINE::dist(p); } double dist(const SEG& b) const { return relation(b) ? 0 : min(min(dist(b.s), dist(b.e)), min(b.dist(s), b.dist(e))); } };
double GetX(const VEC& v, double y) { return v.x / v.y * y; } int main() { int T;
scanf("%d", &T); while (T--) { SEG a, b; a.s.input(); a.e.input(); a.v = a.e - a.s; b.s.input(); b.e.input(); b.v = b.e - b.s; bool fail = false; if (!a.relation(b)) { fail = true; } else { VEC p = a.CrossPoint(b); VEC p1 = a.s.y > a.e.y ? a.s : a.e; VEC p2 = b.s.y > b.e.y ? b.s : b.e; p1 = p1 - p; p2 = p2 - p; double y = min(p1.y, p2.y); if (sgn(y)) { if (p1.y > p2.y) { swap(p1, p2); } int side = sgn(p1.x); if (0 == (side ^ sgn(p2.x)) && p2.relation(p1) == side && sgn(fabs(p1.x) - fabs(p2.x)) <= 0) { fail = true; } if (!fail) { double x1 = GetX(p1, y), x2 = GetX(p2, y); if (x1 > x2) swap(x1, x2); printf("%.2f\n", (x2 - x1) * y / 2 + eps); } } else { fail = true; } } if (fail) { puts("0.00"); } }
return 0; }
|