1 1 0 1 0 1 1 0 0 0 1 1 1
0.408248 0.500000 0.500000 1.000000 0.666667 0.666667 0.666667
模板题:求空间中不平行的两条直线的最短距离及最短线段与两直线的交点
#include
#include
#include
#include
#include
#include
using namespace std;
const double eps = 1e-8;
double Sqr(double a) {
return a * a;
}
double Sqrt(double a) {
return a <= 0 ? 0 : sqrt(a);
}
struct point {
double x, y, z;
point() {}
point(double x, double y, double z) : x(x), y(y), z(z) {}
double length() const {
return Sqrt(Sqr(x)+Sqr(y)+Sqr(z));//线段OP长度
}
};
point operator + (const point &a, const point &b) {//点+点=点
return point(a.x+b.x, a.y+b.y, a.z+b.z);
}
point operator - (const point &a, const point &b) {//点-点=点
return point(a.x-b.x, a.y-b.y, a.z-b.z);
}
point operator * (const point &a, double b) { //点*数 = 点
return point(a.x*b, a.y*b, a.z*b);
}
point det(const point &a, const 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 dot(const point &a, const point &b) {//点积(点*点=数)
return a.x*b.x+a.y*b.y+a.z*b.z;
}
struct line {
point a, b;
line() {}
line(point a, point b) : a(a), b(b) {}
};
double vlen(point p) {return p.length();} //线段OP长度
double lintolin(line u, line v) { //直线到直线距离
point n = det(u.a-u.b, v.a-v.b);
return fabs(dot(u.a-v.a, n))/vlen(n);
}
double angle_cos(line u, line v) { //两直线夹角的cos值
return dot(u.a-u.b, v.a-v.b) / vlen(u.a-u.b) / vlen(v.a-v.b);
}
int T;
double x, y, z;
point a, b, c, d;
void scan(point &a) {
scanf("%lf%lf%lf", &a.x, &a.y, &a.z);
}
void print(const point &a) {
printf("%.6f %.6f %.6f", a.x, a.y, a.z);
}
int main() {
scanf("%d", &T);
while(T--) {
scan(a); scan(b); scan(c); scan(d);
line m(a, b); line n(c, d);
printf("%.6f\n", lintolin(m, n));
point p1 = b - a, p2 = d - c;
point tmp = det(p1, p2);
double t1 = dot(det(c-a,p2), det(p1,p2));
t1 /= tmp.length() * tmp.length();
double t2 = dot(det(c-a,p1), det(p1,p2));
t2 /= tmp.length() * tmp.length();
point mid1 = a + (p1 * t1);
point mid2 = c + (p2 * t2);
print(mid1); printf(" ");
print(mid2); printf("\n");
}
return 0;
}