获得 新的模板了/// 此模板 有线段和线段的最短距离方法,同时包含线段与线段的最短距离;
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<cmath>
#define eps 1e-10
#define inf 0x1f1f1f1f
using namespace std;
int dcmp( double a ){ if( abs(a) < eps ) return 0; if(a > 0) return 1;return -1;}
struct point{
double x,y,z;
point(){}
point( double x,double y,double z ):x(x),y(y),z(z){}
};
typedef point Vector ;
point operator + ( point a,point b ){
return point( a.x+b.x , a.y+b.y , a.z+b.z );
}
// 确定一个平面;一般式;
struct plane{
double a,b,c,d;
plane( double a = 0,double b = 0,double c = 0,double d = 0 ):a(a),b(b),c(c),d(d){}
};
point operator - ( point a,point b ){
return point( a.x-b.x , a.y-b.y, a.z-b.z );
}
point operator * ( point a,double p ){
return point( a.x*p , a.y*p , a.z*p );
}
point operator / ( point a,double p ){
return point( a.x/p , a.y/p , a.z/p );
}
bool operator == ( point a,point b ){
if( dcmp(a.x-b.x) == 0&& dcmp(a.y-b.y) == 0 && dcmp(a.z-b.z) == 0 )return 1;
return 0;
}
double Dot( point a,point b ){ return a.x*b.x + a.y*b.y + a.z*b.z; }
double Length( point a ){ return sqrt(Dot(a,a));}
double Angle( point a,point b ){ return acos(Dot(a,b))/Length(a)/Length(b); }
// 点到 平面p0 - n 的距离;n 必须为单位向量 n 是平面法向量
double p_po_n( const point &p,const point &po,const point n ){
return abs(Dot( p-po,n ));
}
// 点在 平面p0 - n 的投影 ; n 必须为单位向量 n 是平面法向量
point p_po_n_jec( const point &p,const point &p0,const point &n ){
return p-n*Dot( p-p0,n );
}
// 直线p1 p2 在平面 p0 - n 的交点,假设交点存在;唯一
point p_p_p( point p1,point p2,point p0,point n ){
point v = p2 - p1;
double t = ( Dot(n,p0-p1)/Dot(n,p2-p1) );
return p1 + v*t;
}
point cross( point a,point b ){
return point( 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 area( point a,point b,point c ){ return Length(cross(b-a,c-a)); }
double dis_to_line( point p, point a,point b ){
point v1 = b-a, v2 = p-a;
return Length( cross(v1,v2)/Length(v1) );
}
// p 到 ab 线段的距离
double dis_to_segm( point p,point a,point b ){
if( a == b )return Length(p-a);
point v1 = b-a, v2 = p-a, v3 = p-b;
if( dcmp( Dot(v1,v2) ) < 0 ) return Length(v2);
else if( dcmp( Dot(v1,v3) ) > 0 ) return Length(v3);
else return Length(cross(v1,v2))/Length(v1);
}
// 四面体的体积
double dis_l_to_l( point a,point b,point lt,point rt )
{
while( abs(rt.x - lt.x) > eps || abs(rt.y - lt.y) > eps || abs( rt.z - lt.z) > eps )
{
point temp; temp = lt + ( rt - lt )/3.0;
point now; now = lt + ( rt - lt )/3.0*2.0;
if( dis_to_segm(temp,a,b) < dis_to_segm(now,a,b) )
rt = now;
else lt = temp;
}
return dis_to_segm( rt,a,b );
}
// 获取平面 a*x + b*y + c*z + d; 由;两个向量 和 一个平面一个点确定一个平面
plane get_plane( Vector a,Vector b,point c )
{
Vector p = cross( a,b ); // 由平面两个向量 可以确定平面法向量;
double d = ( p.x*c.x + p.y*c.y + p.z*c.z)*-1;
return plane( p.x,p.y,p.z,d );
}
// 获取 直线与平面的交点;
point get_point( plane p,point c,point d )
{
Vector v = c - d;
double t = p.a*c.x+p.b*c.y + p.c*c.z + p.d ;
double s = p.a*(d.x - c.x) + p.b*(d.y-c.y) + p.c*(d.z - c.z);
double k = t/s;
return c + v*k;
}
point A[5];
int main( )
{
int T; scanf("%d",&T);
while( T-- )
{
for( int i = 1; i <= 4; i++ )
scanf("%lf %lf %lf",&A[i].x,&A[i].y,&A[i].z);
Vector v1 = A[2] - A[1];
Vector v2 = A[4] - A[3];
Vector v3 = cross( v1,v2 ); // 获取公垂线;
plane a1 = get_plane( v1,v3,A[1] ); // 两个向量 和一个点 确定一个平面;
plane a2 = get_plane( v2,v3,A[3] );
point p1 = get_point( a1,A[4],A[3] ); // 获取交点;
point p2 = get_point( a2,A[1],A[2] );
printf("%.6lf\n",Length(p1-p2));
printf("%.6lf %.6lf %.6lf %.6lf %.6lf %.6lf\n",p2.x,p2.y,p2.z,p1.x,p1.y,p1.z);
}
return 0;
}