// Arup Guha
// 8/25/2026
// Solution to 2026 UCF Locals Problem: Diamond Cutting

/***

    Let our quadrilaterial be points A, B, C and D read in that order.
    I will treat A as the "bottom" point and C as the "top" point, though
    those descriptions may not actually be accurate, also it's easier to see
    what I am describing if I rotate C to be vertically above A (this transformation
    doesn't fundamentally change anything. I won't physically do these transformations
    but it's just easier to "see" why our technique works if you visualize it like this.

                C

                            B
    D
                A

    We will binary search a parameter, lambda on the four line segments AB (bottom right),
    AD (bottom left), CB (top right), CD (top left). Lambda represents the ratio of the
    total journey from the starting point to the ending point made on the segment.

    If we go lambda of the way from from A to B (call this point E) and
    lambda of the way from C to B (call this point F), it should be fairly clear
    that the line segment formed by those two new points (EF) is vertical, just like AC. (More
    generally, no matter what our picture looks like, this line segment is guaranteed, via
    similar triangles, to be parallel to AC.) Do the same on the other side... to form GH:

                C
            H        F
                            B

    D                E
            G
                A

    Using the same argument, GH is parallel to AC. Although it doesn't look like it on my
    terrible ascii picture, it's guaranteed that EF and GH are the same length, also via
    similar triangles. (It's a proportionality argument. If I travel 1/3 of the way from
    C to B and A to B, then the new vertical line segment has to be 2/3 the length of AC.

    Again, using similar triangles but with ABD similar to AEG and CBD similar to CFH, we
    can prove that those two segments are also parallel. Thus, the four points this
    process produces are guaranteed to form a parallelogram, where either FH < HG or
    FH > HG or the two are equal. Thus, we can binary search the value of lambda. If
    we try some value of lambda and FH < HG, then we know the real answer is a bigger
    value of lambda, which will increase FH and decrease HG. Similarly, if FH > HG, then
    we want to guess a smaller lambda.

    For real-valued binary searches, I like running a fixed number of iterations. I don't
    want 100 iterations to TLE, so that's what I put in here.
***/

using namespace std;

#include <bits/stdc++.h>

// A basic point class.
class pt {

    public:
        double x;
        double y;

        pt() {
            x = 0;
            y = 0;
        }

        pt(double myx, double myy) {
            x = myx;
            y = myy;
        }

        // Returns the vector from this point to e.
        pt getDirTo(pt e) {
            return pt(e.x-x, e.y-y);
        }

        // Returns the distance between this point and e.
        double distTo(pt e) {
            return sqrt( (e.x-x)*(e.x-x) + (e.y-y)*(e.y-y) );
        }
};

// Line segment class.
class lineseg {

    public:
        pt s;
        pt e;
        pt dir;

        // I set the start and end and the direction vector.
        lineseg(pt mys, pt mye) {
            s = mys;
            e = mye;
            dir = s.getDirTo(e);
        }

        // Returns the pt that is lambda from start to end. If lambda = 0, start is returned.
        // If lambda = 1, end is returned. lambda is in between 0 and 1 for this problem.
        pt getPtOnSeg(double lambda) {
            return pt(s.x+lambda*dir.x, s.y+lambda*dir.y);
        }
};

void solve(vector<pt>& quad);

int main() {

    // Process cases.
    int nC;
    cin >> nC;
    for (int loop=0; loop<nC; loop++) {

        vector<pt> quad;
        for (int i=0; i<4; i++) {
            pt tmp;
            cin >> tmp.x >> tmp.y;
            quad.push_back(tmp);
        }

        // Do it!
        solve(quad);
    }

    return 0;
}

// Solves one case.
void solve(vector<pt>& quad) {

    // These are the four relevant line segments.
    lineseg bottomRight(quad[0], quad[1]);
    lineseg bottomLeft(quad[0], quad[3]);
    lineseg topRight(quad[2], quad[1]);
    lineseg topLeft(quad[2], quad[3]);

    // Run real valued binary search.
    double low = 0, high = 1;
    for (int i=0; i<100; i++) {

        double mid = (low+high)/2;

        // Get the four points of interest based on this value of lambda for each line segment.
        // Yes, we need to use the same value of lambda for each line segment!
        pt bRight = bottomRight.getPtOnSeg(mid); // seg 1
        pt bLeft = bottomLeft.getPtOnSeg(mid); // seg 4
        pt tRight = topRight.getPtOnSeg(mid); // seg 2
        pt tLeft = topLeft.getPtOnSeg(mid); // seg 3

        // Get the distance "across", connecting segment 2 to segment 3 (one based)
        double dAcross = tLeft.distTo(tRight);

        // Get the distance "updown" connecting segment 3 to segment 4 (one based)
        double dUpDown = tLeft.distTo(bLeft);

        // We have to make the portion along the "top" longer.
        if (dAcross < dUpDown)
            low = mid;

        // We have to make that portion smaller...
        else
            high = mid;
    }

    // Build answer in counter-clockwise order.
    vector<pt> res;
    res.push_back(bottomRight.getPtOnSeg(low));
    res.push_back(topRight.getPtOnSeg(low));
    res.push_back(topLeft.getPtOnSeg(low));
    res.push_back(bottomLeft.getPtOnSeg(low));

    // Ta da!
    for (int i=0; i<4; i++)
        cout << setprecision(12) << res[i].x << " " << res[i].y << "\n";
}







