SaveLabmanNo.004
杭州区的网络赛,求异面直线的最短距离,及公垂线与两条直线的交点坐标,这题开始直接用公式计算WA了无数次, 如果直接用公式计算,改用用long double保存中间计算结果,可以Accept.
下面贴的是一个向量法的代码
:::c++
#include<cstdio>
#include<cstring>
#include<cmath>
#define eps (1e-10);
struct point{
double x,y,z;
};
double dot3(point a,point b){
return a.x*b.x+a.y*b.y+a.z*b.z;
}
point cross3(point a,point b){
point ret;
ret.x=a.y*b.z-a.z*b.y;
ret.y=a.z*b.x-b.z*a.x;
ret.z=a.x*b.y-b.x*a.y;
return ret;
}
point vvv(point a,point b){
point ret;
ret.x=a.x-b.x;
ret.y=a.y-b.y;
ret.z=a.z-b.z;
return ret;
}
double dis3(point a,point b){
double x=a.x-b.x;
double y=a.y-b.y;
double z=a.z-b.z;
return sqrt(x*x+y*y+z*z);
}
double mo(point a){
return sqrt(a.x*a.x+a.y*a.y+a.z*a.z);
}
int main(){
point a,b,c,d;
int ca;
scanf("%d",&ca);
while(ca--){
point v;//公垂线
point vl1,vl2,tv;
point m;//面的法向量
scanf("%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&a.z,&b.x,&b.y,&b.z);
scanf("%lf%lf%lf%lf%lf%lf",&c.x,&c.y,&c.z,&d.x,&d.y,&d.z);
vl1=vvv(a,b);
vl2=vvv(c,d);
v=cross3(vl1,vl2);//求公垂线方向向量
m=cross3(v,vl1);//ab与公垂线的所成面的法向量
tv=vvv(a,c);//ab为平面内直线
double mydis=fabs(dot3(v,tv))/mo(v);
double t=dot3(m,tv)/dot3(m,vl2);
double x1=c.x+vl2.x*t;
double y1=c.y+vl2.y*t;
double z1=c.z+vl2.z*t;
tv=vvv(c,a);
m=cross3(v,vl2);
t=dot3(m,tv)/dot3(m,vl1);
double x2=a.x+vl1.x*t;
double y2=a.y+vl1.y*t;
double z2=a.z+vl1.z*t;
printf("%.6lf\n",mydis);
printf("%.6lf %.6lf %.6lf %.6lf %.6lf %.6lf\n",x2,y2,z2,x1,y1,z1);
}
}