【题意】求两条空间异面直线的最短距离,和取得这个最短距离的两个直线上的坐标。
【解题方法】板子一通套。
【AC 代码】
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const double eps = 1e-8;
//三维空间点
struct Point
{
double x, y, z;
Point(double x=0,double y=0,double z=0): x(x),y(y),z(z){}
Point(const Point& a)
{
x = a.x;
y = a.y;
z = a.z;
return;
}
void Print()
{
printf("%lf %lf %lf\n", x, y, z);
}
Point operator + (Point &t)
{
return Point(x+t.x, y+t.y, z+t.z);
}
};
//空间直线
struct Line
{
Point a,b;
};
//空间平面
struct Plane
{
Point a,b,c;
Plane(){}
Plane(Point a, Point b, Point c):a(a),b(b),c(c){}
void showPlane()
{
a.Print();
b.Print();
c.Print();
return;
}
};
double dcmp(double t)
{
if(fabs(t) < eps) return 0;
return t < 0 ? -1 : 1;
}
//三维叉积
Point cross(Point u,Point v)
{
Point ret;
ret.x = u.y * v.z - v.y * u.z;
ret.y = u.z * v.x - u.x * v.z;
ret.z = u.x * v.y - u.y * v.x;
return ret;
}
//三维点积
double multi(Point u,Point v)
{
return u.x * v.x + u.y * v.y + u.z * v.z;
}
//矢量差
Point sub(Point u,Point v)
{
Point ret;
ret.x = u.x - v.x;
ret.y = u.y - v.y;
ret.z = u.z - v.z;
return ret;
}
//两点距离
double dist(Point p1, Point p2)
{
return sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y) + (p1.z-p2.z)*(p1.z-p2.z));
}
//向量的模
double VectorLength(Point p)
{
return sqrt(p.x*p.x + p.y*p.y + p.z*p.z);
}
//空间直线距离
double LineToLine(Line u,Line v,Point &tmp )
{
tmp = cross(sub(u.a,u.b),sub(v.a,v.b));
return fabs(multi(sub(u.a,v.a),tmp))/VectorLength(tmp);
}
//取平面法向量
Point normalVector(Plane s)
{
return cross(sub(s.a,s.b),sub(s.b,s.c));
}
//空间平面与直线的交点
Point Intersection(Line l,Plane s)
{
Point 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)
{
Point normal;
double ans=LineToLine(A,B,normal);
printf("%.6f\n",ans);
Plane alpha=Plane(A.a,A.b,A.a+normal);
Plane beta=Plane(B.a,B.b,B.a+normal);
Point u=Intersection(B,alpha);
Point v=Intersection(A,beta);
printf("%.6f %.6f %.6f %.6f %.6f %.6f\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);
}
}