给定三维空间中的两个点A(x_1,y_1,z_1),B(x_2,y_2,z_2)A(x1,y1,z1),B(x2,y2,z2),以及点P(x,y,z)P(x,y,z)。

请计算点P到线段AB的最短距离。

15795284874929.png

输入

第一行有一个整数T(1<=T<=10000),表示测试数据的数目。

接下来T行,每行有9个整数x_1,y_1,z_1,x_2,y_2,z_2,x,y,zx1,y1,z1,x2,y2,z2,x,y,z

坐标的值是整数,且绝对值不超过100。

输出

对于每个测试用例,输出答案与标准答案误差不得超过0.01

样例

输入

复制
2
0 0 1 0 1 1 0 1 0
0 0 0 1 1 1 0 0 1

输出

复制
1.00
0.82

提示

子任务1,40分,z_1=0, z_2=0, z=0z1=0,z2=0,z=0

子任务2,60分,全范围。

#pragma warning(disable:4996)
#include <cstdio>
#include <vector>
#include <cmath>
int main()
{
    int n;
    scanf("%d", &n);
    double x1, y1, z1, x2, y2, z2, x, y, z;
    for (int i = 0; i < n; i++)
    {
        scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf", &x1, &y1, &z1, &x2, &y2, &z2, &x, &y, &z);
        double ax = x2 - x1;
        double ay = y2 - y1;
        double az = z2 - z1;
        double bx = x - x1;
        double by = y - y1;
        double bz = z - z1;
        double cx = x - x2;
        double cy = y - y2;
        double cz = z - z2;
        double adotb = ax * bx + ay * by + az * bz;
        double adotc = -ax * cx + -ay * cy + -az * cz;
        double a2 = ax * ax + ay * ay + az * az;
        double b2 = bx * bx + by * by + bz * bz;
        double c2 = cx * cx + cy * cy + cz * cz;
        if (adotb <= 0)
        {
            printf("%.2f\n", sqrt(b2));
        }
        else if (adotc <= 0)
        {
            printf("%.2f\n", sqrt(c2));
        }
        else
        {
            printf("%.2f\n", sqrt(b2 - adotb * adotb / a2));
        }
    }
    return 0;
}