给定三维空间中的两个点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的最短距离。
输入
第一行有一个整数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 ", sqrt(b2)); } else if (adotc <= 0) { printf("%.2f ", sqrt(c2)); } else { printf("%.2f ", sqrt(b2 - adotb * adotb / a2)); } } return 0; }