hdoj 4741 异面直线求最近距离及最近点

来源:互联网 发布:sql语句去重查询 编辑:程序博客网 时间:2024/05/09 05:16

hdoj 4741

拯救助手!

题意:建立时空隧道,连接Alpha与Beta世界线,求两世界线的最短距离和最近点位置。

思路:三维向量A、B叉乘结果是叉乘向量的垂直向量C,在原直线A上任选一点V向C移动,移动的这段向量也是和B垂直的,这时候用V和直线A做平面Alpha,Alpha就是B的垂直平面,同理可以得到A的垂直平面Beta,而Alpha与B的交点和Beta和A的交点就是两直线最近点,至于最近距离,可以用两点距离求,也可以直接套公式。

上交大的模板~

El Psy Congroo!

我是桶子。

#include <cstdio>#include <cmath>const double eps = 1e-8;const double PI = acos(-1.0);inline double Sqrt(double a){    return a <= 0 ? 0 : sqrt(a);}inline double Sqr(double a){    return a * a;}class Point_3{public:    double x, y, z;    Point_3(){}    Point_3(double x, double y, double z):x(x), y(y), z(z){}    void input(){        scanf("%lf %lf %lf", &x, &y, &z);    }    double Length() const{        return Sqrt(Sqr(x) + Sqr(y) + Sqr(z));    }};Point_3 operator + (const Point_3 &a, const Point_3 &b){    return Point_3(a.x + b.x, a.y + b.y, a.z + b.z);}Point_3 operator - (const Point_3 &a, const Point_3 &b){    return Point_3(a.x - b.x, a.y - b.y, a.z - b.z);}Point_3 operator * (const Point_3 &a, double b){    return Point_3(a.x * b, a.y * b, a.z * b);}//叉乘Point_3 Det(const Point_3 &a, const Point_3 &b){    return Point_3(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_3 &a, const Point_3 &b){    return a.x * b.x + a.y * b.y + a.z * b.z;}class Line_3{public:    Point_3 a, b;    Line_3(){}    Line_3(Point_3 a, Point_3 b): a(a), b(b){}};class Plane_3{public:    Point_3 a, b, c;    Plane_3(){}    Plane_3(Point_3 a, Point_3 b, Point_3 c):a(a), b(b), c(c){}};//直线到直线的距离 w是垂直向量double LineToLine(Line_3 u, Line_3 v, Point_3 &w){    w = Det(u.a - u.b, v.a - v.b);    return fabs(Dot(u.a - v.a, w) / w.Length());}//平面法向量Point_3 Pvec(Point_3 s1, Point_3 s2, Point_3 s3){    return Det(s1 - s2, s2 - s3);}//直线与平面的交点Point_3 Intersection(Line_3 l, Plane_3 s){    Point_3 ret = Pvec(s.a, s.b, s.c);    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 = l.a + (l.b - l.a) * t;    return ret;}main() {    int n;    scanf("%d", &n);    while(n--) {        Point_3 a, b, c, d;        a.input(), b.input(), c.input(), d.input();        Line_3 l1(a, b), l2(c, d);        Point_3 v;        double dist = LineToLine(l1, l2, v);        Plane_3 p1(l1.a, l1.b, l1.a + v), p2(l2.a, l2.b, l2.a + v);        Point_3 ans1 = Intersection(l1, p2);        Point_3 ans2 = Intersection(l2, p1);        printf("%.6f\n", dist);        printf("%.6f %.6f %.6f %.6f %.6f %.6f\n", ans1.x, ans1.y, ans1.z, ans2.x, ans2.y, ans2.z);    }}

 


0 0
原创粉丝点击