SaveLabmanNo.004

发表于: 2013年09月20 00:00

杭州区的网络赛,求异面直线的最短距离,及公垂线与两条直线的交点坐标,这题开始直接用公式计算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);
	}
}
© 2018 - fluyy - 粤ICP备17114935号-1