/* 向量运算不会呐 抄了一个长度几百行的模板 一直过不了编译 醉了 还是抄了大佬的代码 首先把所有的线段投影到 导轨上 然后用set 分上和下分别维护一下 距离导轨最近的线段 是能够照射到的 可以证明 我们的最优答案有一端肯定是在线段的分界点上的 所以我们可以用扫描线思想 从一端扫到另一端 端点为各个分界点 这样正这反着处理两遍即可 long double 怎么输出啊 在线等挺急的 */ #include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<cmath> #include<set> #define sqr(x) (x) * (x) #define ld long double #define ll long long #define M 20010 using namespace std; int read() { int nm = 0, f = 1; char c = getchar(); for(; !isdigit(c); c = getchar()) if(c == '-') f = -1; for(; isdigit(c); c =getchar() ) nm = nm * 10 + c - '0'; return nm * f; } const ld eps = 1e-9, zz = 0; ld x[M][2], y[M][2], len[M] ,ver[M], z[M], x0; int p[M] , n,m; bool cmp(int a, int b) { return (a > 0 ? x[a][0] : x[-a][1]) < (b > 0 ? x[b][0]: x[-b][1]); } struct L { int t; bool operator <( const L &b) const { ld w1 = (y[t][1] - y[t][0]) / (x[t][1] - x[t][0]) * (x0 - x[t][0])+y[t][0]; ld w2 = (y[b.t][1] - y[b.t][0]) / (x[b.t][1] - x[b.t][0]) * (x0 - x[b.t][0]) + y[b.t][0]; return fabs(w1) < fabs(w2); } }; set<L>up, down; int main() { int t = read(); while(t--) { n = read(); for(int i = 1; i <= n; i++) { x[i][0] = read(), y[i][0] = read(), x[i][1] = read(), y[i][1] = read(); len[i] = sqrt(sqr(x[i][0] - x[i][1]) + sqr(y[i][0] - y[i][1])); } ld xn0 = read(), yn0 = read(), xn1 = read(), yn1 = read(), lenx = read(); if(xn0 > xn1) swap(xn0, xn1), swap(yn0, yn1); ld dx = xn1 - xn0, dy = yn1 - yn0, le = sqrt(sqr(dx) + sqr(dy)),Sin = dy / le, Cos = dx / le; for(int i = 1; i <= n; i++) { x[i][0] -= xn0, x[i][1] -= xn0, y[i][1] -= yn0, y[i][0] -= yn0; ld a,b,c,d; a = x[i][0] * Cos + y[i][0] * Sin; b = x[i][0] * Sin - y[i][0] * Cos; c = x[i][1] * Cos + y[i][1] * Sin; d = x[i][1] * Sin - y[i][1] * Cos; x[i][0] = a, y[i][0] = -b, x[i][1] = c, y[i][1] = -d; } for(int i = 1; i <= n; i++) { if(x[i][0] > x[i][1]) swap(x[i][0], x[i][1]), swap(y[i][0], y[i][1]); len[i] = len[i] /(x[i][1] - x[i][0]); } m = 0; for(int i = 1; i <= n; i++) p[++m] = i, p[++m] = -i; sort(p + 1, p + m + 1, cmp); for(int i = 1; i <= m ; i++) ver[i] = 0; for(int i = 1, a; i <= m; i++) { if(p[i] > 0) { a = p[i], z[i] = x0 = x[a][0]; if(y[a][0] > 0) up.insert((L){a}); else down.insert((L){a}); } else{ a = -p[i], z[i] = x0 = x[a][1]; if(y[a][0] > 0) up.erase((L){a}); else down.erase((L){a}); } if(!up.empty()) ver[i] += len[(*up.begin()).t]; if(!down.empty()) ver[i] += len[(*down.begin()).t]; } ld ans = 0, sum = 0; z[m + 1] = 1e16; for(int i = 1, l = 1; i <= m; i++){ sum += (z[i] - z[i - 1]) * ver[i - 1]; while(z[i] - z[l + 1] > lenx) l++, sum -= (z[l] - z[l - 1]) * ver[l - 1]; ans = max(ans, sum - max(zz, (z[i] - z[l] - lenx) * ver[l])); } sum = 0; for(int i = m, r = m; i >= 1; i--) { sum += (z[i + 1] - z[i]) * ver[i]; while(z[r - 1] - z[i] > lenx) --r, sum -= (z[r + 1] - z[r]) * ver[r]; ans = max(ans, sum - max(zz, (z[r] - z[i] - lenx) * ver[r - 1])); } //cout << ans << " "; double as = ans; printf("%.15lf ", as); } return 0; }