空间中直线之间距离介绍及原码

来源:互联网 发布:明天教室网络课怎么样 编辑:程序博客网 时间:2024/05/01 19:11

三维直线与直线之间的距离:
(由于用word中公式编辑器所编写的公式复制过来显示的有问题,后面贴了文档中的段落图片,以便读者看清楚)

假设有两条直线L_0 (s)=P_0+s(d_0 ) ⃗ 和L_1 (t)=P_1+t(d_1 ) ⃗ ,设Q_0=P_0+s_c (d_0 ) ⃗ 和Q_1=P_1+t_c (d_1 ) ⃗ 为分别位于P_0和P_1处的点,它们之间的距离为最小距离,并设v ⃗=Q_0-Q_1(如下图所示)。

图1

  

图1两条直线之间的距离

最小距离的关键是求得公垂线,即这两点之间的线同时垂直这两条直线。须满足数学公式:
(d_0 ) ⃗∙v ⃗=0
(d_1 ) ⃗∙v ⃗=0                                                    (1)
使用v ⃗的定义式,
v ⃗=Q_0-Q_1=P_0+s_c (d_0 ) ⃗-P_1-t_c (d_1 ) ⃗ (2)
将(2)式带入方程(1),可得
((d_0 ) ⃗∙(d_0 ) ⃗ ) s_c-((d_0 ) ⃗∙(d_1 ) ⃗ ) t_c=-(d_0 ) ⃗∙(P_0-P_1)
((d_1 ) ⃗∙(d_0 ) ⃗ ) s_c-((d_1 ) ⃗∙(d_1 ) ⃗ ) t_c=-(d_1 ) ⃗∙(P_0-P_1)
设a=(d_0 ) ⃗∙(d_0 ) ⃗,b=(d_0 ) ⃗∙(d_1 ) ⃗,c=(d_1) ⃗∙(d_1 ) ⃗,d=(d_0 ) ⃗∙(P_0-P_1),e=(d_1 ) ⃗∙(P_0-P_1),且f=(P_0-P_1)∙(P_0-P_1)。由这两个方程可以求出两个未知数,其解为:
s_c=(be-cd)/(ac-b^2 )
t_c=(ae-bd)/(ac-b^2 )
若分母ac-b^2<ε, 那么直线L_0和L_1平行。在该情况下,我们可以选取任意t_c的值来计算s_c。通过设t_c=0,可以将计算量减到最小程度,此时仅计算s_c=-d/a。
只要计算到了最接近的点的参数值,就能计算出这两条直线之间的距离:
||L_0 (s_c )-L_1 (t_c )||=||(P_0-P_1 )+((be-cd) (d_0 ) ⃗-(ae-bd)(d_1) ⃗)/(ac-b^2 )||


求三维直线间距离的代码(使用Ogre的数据类型):
Ogre::Real getIntersectPointOnSegment(const Ogre::Vector3& line0Base, constOgre::Vector3& line0Direction, const Ogre::Vector3& line1Base, constOgre::Vector3& line1Direction)
{
    Ogre::Vector3 u = line0Base – line1Base;
    Ogre::Real a = line0Direction.dotProduct(line0Direction);
    Ogre::Real b = line0Direction.dotProduct(line1Direction);
    Ogre::Real c = line1Direction.dotProduct(line1Direction);
    Ogre::Real d = line0Direction.dotProduct(u);
    Ogre::Real e = line1Direction.dotProduct(u);
    Ogre::Real f = u.dotProduct(u);
    Ogre::Real det = a*c - b*b;

    // check for (near) parallelism
    if (det < FLT_EPSILON)
    {
        // Arbitrarily choose the base pointof line0
        t = 0;
        // choose largest denominator tominimize float point problems
        if (a > b)
        {
            s = -d / a;
        }
        else
        {
            s = -e / b;
        }
        return d * s + f;
    }
    else
    {

        // Nonparallel lines
        Ogre::Real invDet =1 / det;
        s = (b * e – c * d) * invDet;
        t = (a * e – b * d) * invDet;
        return s * ( a*s + b*t + 2*d) + t *(b*s + c*t + 2*e) + f;
    }
}


附件图片:

段落1


段落2

 

0 0