三维几何-点和直线

直线的表示。

直线仍然可以用参数方程(点和向量)来表示,并且射线和线段仍然可以看成参数有取值范围限制的直线,并且点到直线的投影和二维情形一样。

点到直线/线段的距离。仍然可以用面积法(注意三维叉积是向量,要用Length函数而不是fabs)。

点P到直线AB的距离:

double DistanceToLine(const Point3 &P, const Point3 &A, const Point3 &B)
{
    Vector3 v1, v2;

    v1 = B - A;
    v2 = P - A;
    return Length(Cross(v1, v2)) / Length(v1);
}

点P到线段AB的距离。

double DistanceToSegment(const Point3 &P, const Point3 &A, const Point3 &B)
{
    if(A == B)
        return Length(P-A);

    Vector3 v1, v2, v3;

    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);
}

异面直线的最短距离:

假设两条直线分别为l1=(p1,v1)和l2=(p2,v2),那么最短距离会在某个q1=p1 + sv1 和 q2 = p2 + tv2 上取到,其中q1和q2分别在l1和l2上

且q1q2是这两条异面直线的公垂线。向量q1q2=q2-q1 = p2-p1 + tv2-sv1垂直于v1, 因此Dot(p2-p1+tv2-sv1)=0.分配率:

Dot(p2-p1,v1) + t*Dot(v2,v1)-s*Dot(v1,v1)=0. 根据q1q2垂直于v2还可以得到一个一次方程,联立。

求异面直线p1+su和p2+tv的公垂线对应的s.如果平行/重合,则返回false。
两条直线相交的情况下算出的距离为0,并且返回true。

bool LineDistance3D(const Point3 &P1,const Vector3 &u,const Point3 &P2,const Vector3 &v, double &s)
{
    double a, b;

    b = Dot(u, u)*Dot(v, v) - Dot(u, v)*Dot(u, v);
    if(dcmp(b) == 0)
        return false;

    a = Dot(u, v)*Dot(v, P1-P2) - Dot(v, v)*Dot(u, P1-P2);
    s = a / b;
    return true;
}

 

    原文作者:算法
    原文地址: https://www.twblogs.net/a/5bd3a0592b717778ac209bee
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞