hdu 4741 Save Labman No.004异面直线间的距离既构成最小距离的两个端点

Save Labman No.004

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1473    Accepted Submission(s): 484

Problem Description

Due to the preeminent research conducted by Dr. Kyouma, human beings have a breakthrough in the understanding of time and universe. According to the research, the universe in common sense is not the only one. Multi World Line is running simultaneously. In simplicity, let us use a straight line in three-dimensional coordinate system to indicate a single World Line.

During the research in World Line Alpha, the assistant of Dr. Kyouma, also the Labman No.004, Christina dies. Dr. Kyouma wants to save his assistant. Thus, he has to build a Time Tunnel to jump from World Line Alpha to World Line Beta in which Christina can be saved. More specifically, a Time Tunnel is a line connecting World Line Alpha and World Line Beta. In order to minimizing the risks, Dr. Kyouma wants you, Labman No.003 to build a Time Tunnel with shortest length.

Input

The first line contains an integer T, indicating the number of test cases.

Each case contains only one line with 12 float numbers (x1, y1, z1), (x2, y2, z2), (x3, y3, z3), (x4, y4, z4), correspondingly indicating two points in World Line Alpha and World Line Beta. Note that a World Line is a three-dimensional line with infinite length.

Data satisfy T <= 10000, |x, y, z| <= 10,000.

Output

For each test case, please print two lines.

The first line contains one float number, indicating the length of best Time Tunnel.

The second line contains 6 float numbers (xa, ya, za), (xb, yb, zb), seperated by blank, correspondingly indicating the endpoints of the best Time Tunnel in World Line Alpha and World Line Beta.

All the output float number should be round to 6 digits after decimal point. Test cases guarantee the uniqueness of the best Time Tunnel.

Sample Input

1
1 0 1 0 1 1 0 0 0 1 1 1

Sample Output

0.408248
0.500000 0.500000 1.000000 0.666667 0.666667 0.666667

Source

2013 ACM/ICPC Asia Regional Hangzhou Online

有必要拿出空间解析几何出来看看了,尼玛用平面方程跟直线方程求解的时候除数为零了。最后没办法只能看大神的模版了。。。。

大概解题思路:先求出两直线的公垂线(两方向向量的叉积),以公垂线跟一直线形成一平面求另一直线与该平面的交点。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;

const double eps = 1e-8;
struct Point3//三维空间点
{
    double x, y, z;
    Point3(double x=0,double y=0,double z=0): x(x),y(y),z(z){}
    Point3 operator + (Point3 &t){return Point3(x+t.x, y+t.y, z+t.z);}
    Point3 operator - (Point3 &t) {return Point3(x-t.x, y-t.y, z-t.z);}
    Point3 operator * (double p) {return Point3(x*p, y*p, z*p);}
    Point3 operator / (double p) {return Point3(x/p, y/p, z/p);}
};
typedef Point3 Vector3;
struct Line//空间直线
{
    Point3 a,b;
};
struct Plane//空间平面
{
    Point3 a,b,c;
    Plane(){}
    Plane(Point3 a, Point3 b, Point3 c):a(a),b(b),c(c){}
};
int dcmp(double x)
{
    if(fabs(x) < eps) return 0;
    return x < 0 ? -1 : 1;
}
double Dot(Vector3 A,Vector3 B) { return A.x*B.x + A.y*B.y + A.z*B.z; }
double Length2(Vector3 A) { return Dot(A, A); }
Vector3 Cross(Vector3 A, Vector3 B) { return Vector3(A.y*B.z - A.z*B.y, A.z*B.x - A.x*B.z, A.x*B.y - A.y*B.x); }

double LineToLine(Line u,Line v,Vector3 &t)//空间直线间距离
{
    t=Cross(u.a-u.b,v.a-v.b);
    return fabs(Dot(u.a-v.a,t))/sqrt(Length2(t));
}

Vector3 normalVector(Plane s)//取平面法向量
{
    return Cross(s.a-s.b,s.b-s.c);
}

Point3 Intersection(Line l,Plane s)//空间平面与直线的交点
{
    Point3 ret = normalVector(s);
    double t = (ret.x*(s.a.x-l.a.x)+ret.y*(s.a.y-l.a.y)+ret.z*(s.a.z-l.a.z))
        /(ret.x*(l.b.x-l.a.x)+ret.y*(l.b.y-l.a.y)+ret.z*(l.b.z-l.a.z));
    ret.x = l.a.x + ( l.b.x - l.a.x ) * t;
    ret.y = l.a.y + ( l.b.y - l.a.y ) * t;
    ret.z = l.a.z + ( l.b.z - l.a.z ) * t;
    return ret;
}

void solve(Line A, Line B)
{
    Vector3 normal;
    double d = LineToLine(A,B,normal);
    printf("%.6lf\n",d);
    Plane pa = Plane(A.a,A.b,A.a+normal);
    Plane pb  = Plane(B.a,B.b,B.a+normal);
    Point3 u = Intersection(B,pa);
    Point3 v = Intersection(A,pb);
    printf("%.6lf %.6lf %.6lf %.6lf %.6lf %.6lf\n", v.x, v.y, v.z, u.x, u.y, u.z );
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        Line A,B;
        scanf("%lf%lf%lf", &A.a.x, &A.a.y, &A.a.z);
        scanf("%lf%lf%lf", &A.b.x, &A.b.y, &A.b.z);
        scanf("%lf%lf%lf", &B.a.x, &B.a.y, &B.a.z);
        scanf("%lf%lf%lf", &B.b.x, &B.b.y, &B.b.z);
        solve(A,B);
    }
    return 0;
}

hdu 4741 Save Labman No.004异面直线间的距离既构成最小距离的两个端点

时间: 2024-10-28 06:12:45

hdu 4741 Save Labman No.004异面直线间的距离既构成最小距离的两个端点的相关文章

HDU 4741 Save Labman No.004

题意:求空间两线的最短距离和最短线的交点 题解: 线性代数和空间几何,主要是用叉积,点积,几何. 知道两个方向向量s1,s2,求叉积可以得出他们的公共垂直向量,然后公共垂直向量gamma和两线上的点形成的向量做内积, 在除掉gamma的长度就得到投影,即是最短距离. 然后求两个点可以用gamma和s2的叉积和l2上的一个点描述一个平面,再求平面和线的交点, 把(p2-p1)*n 和(p0-p1)*n相除算出比例乘上p2-p1得到交点和p1的差,再加上p1就求出交点了 学习点:计算几何的一些东西

HDU 4741

求异面直线距离及公垂线 公式转自:http://blog.csdn.net/zhengnanlee/article/details/11870595  (求公垂线) 两条直线: 构造方程: 求出公垂线向量: 记公垂线和l1形成的平面为alpha,下面求它: 令: 联立: #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmat

HDU 2001 计算两点间的距离

Problem Description 输入两点坐标(X1,Y1),(X2,Y2),计算并输出两点间的距离. Input 输入数据有多组,每组占一行,由4个实数组成,分别表示x1,y1,x2,y2,数据之间用空格隔开. Output 对于每组输入数据,输出一行,结果保留两位小数. Sample Input 0 0 0 1 0 1 1 0 Sample Output 1.00 1.41 题意:输入两点坐标(X1,Y1),(X2,Y2),计算并输出两点间的距离. #include <stdio.h>

HDOJ/HDU 2547 无剑无我(两点间的距离)

Problem Description 北宋末年,奸臣当道,宦官掌权,外侮日亟,辽军再犯.时下战火连连,烽烟四起,哀鸿遍野,民不聊生,又有众多能人异士群起而反,天下志士云集响应,景粮影从. 值此危急存亡之秋,在一个与世隔绝的地方-MCA山上一位江湖人称<英雄哪里出来>的人正在为抗击辽贼研究剑法,终于于一雷电交加之夜精确计算出了荡剑回锋的剑气伤害公式. 定义 f(x, y, m, n) = sqrt(x*x + y*y + m*m + n*n - 2*m*x - 2*n*y); hint : s

计算两点间的距离

计算两点间的距离 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 208295    Accepted Submission(s): 72641 Problem Description 输入两点坐标(X1,Y1),(X2,Y2),计算并输出两点间的距离. Input 输入数据有多组,每组占一行,由4个实数组成,分别表示x1,y1,x2,y

计算两点间的距离-hdu2001

Problem Description 输入两点坐标(X1,Y1),(X2,Y2),计算并输出两点间的距离. Input 输入数据有多组,每组占一行,由4个实数组成,分别表示x1,y1,x2,y2,数据之间用空格隔开. Output 对于每组输入数据,输出一行,结果保留两位小数. Sample Input 0 0 0 1 0 1 1 0 Sample Output 1.00 1.41 1 #include<stdio.h> 2 #include<math.h> 3 int main

HDOJ 2001 计算两点间的距离

计算两点间的距离 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 94573    Accepted Submission(s): 36296 Problem Description 输入两点坐标(X1,Y1),(X2,Y2),计算并输出两点间的距离. Input 输入数据有多组,每组占一行,由4个实数组成,分别表示x1,y1,x2,y

ios根据gps坐标来计算两点间的距离

//ios根据gps坐标来计算两点间的距离 //x1,y1 点1的坐标 x2,y2点2的坐标 -(double) gps2m:(double)x1 _y1:(double)y1 _x2:(double)x2 _y2:(double)y2{ double radLat1 = (x1 * 3.1416 / 180.0); double radLat2 = (x2 * 3.1416 / 180.0); double a = radLat1 - radLat2; double b = (y1 - y2)

nyist 101 两点间的距离 ----rwkj 1284

101 两点距离时间限制:3000 ms | 内存限制:65535 KB 难度:1描述 输入两点坐标(X1,Y1),(X2,Y2)(0<=x1,x2,y1,y2<=1000),计算并输出两点间的距离.输入第一行输入一个整数n(0<n<=1000),表示有n组测试数据;随后每组占一行,由4个实数组成,分别表示x1,y1,x2,y2,数据之间用空格隔开.输出对于每组输入数据,输出一行,结果保留两位小数.样例输入20 0 0 10 1 1 0样例输出1.001.41 #include&l