三維幾何-點和直線

直線的表示。

直線仍然可以用參數方程(點和向量)來表示,並且射線和線段仍然可以看成參數有取值範圍限制的直線,並且點到直線的投影和二維情形一樣。

點到直線/線段的距離。仍然可以用面積法(注意三維叉積是向量,要用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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章