【问题标题】:Distance from origin to plane (shortest)原点到平面的距离(最短)
【发布时间】:2011-12-16 21:45:10
【问题描述】:

所以我正在阅读此页面上的某些内容 (http://gamedeveloperjourney.blogspot.com/2009/04/point-plane-collision-detection.html)

作者提到

 d = - D3DXVec3Dot(&vP1, &vNormal);

其中 vP1 是平面上的一个点,vNormal 是平面的法线。我很好奇这如何使您与世界原点的距离保持一致,因为结果将始终为 0。此外,为了清楚起见(因为我对平面方程的 d 部分仍然有些模糊),平面方程中的d是通过世界原点的直线到平面原点的距离吗?

【问题讨论】:

    标签: math 3d


    【解决方案1】:

    在一般情况下,点p 和平面之间的距离可以通过

    <p - p0, normal>
    

    &lt;a, b&gt; 是点积运算

    <a, b> = ax*bx + ay*by + az*bz
    

    其中p0 是平面上的一个点。

    n 为单位长度时,向量之间的点积和它是向量在法线上的投影的(有符号)长度

    您报告的公式只是点 p 是原点时的特例。在这种情况下

    distance = <origin - p0, normal> = - <p0, normal>
    

    这个等式在形式上是错误的,因为点积是关于向量,而不是点......但在数字上仍然成立。写下你得到的明确公式

    (0 - p0.x)*n.x + (0 - p0.y)*n.y + (0 - p0.z)*n.z
    

    相同
    - (p0.x*n.x + p0.y*n.y + p0.z*n.z)
    

    确实,存储平面的好方法是保存正常的nk = &lt;p0, n&gt; 的值,其中p0 是平面上的任意点(k 的值与您选择的点无关飞机)。

    【讨论】:

    • 法线是表面平面的法线。如果该点已经是平面上的一个点,那么它们将成 90 度角,因此答案将始终为 0。我不明白这是从原点到平面的距离,特别是如果平面是与原点的随机距离。此外,就找出点与表面的关系而言,我确实理解了它在逻辑和几何上的含义。让我赶上的唯一一件事就是这个。
    【解决方案2】:

    结果并不总是零。只有当飞机经过原点时,结果才会为零。 (这里假设飞机没有经过原点。)

    基本上,您会得到一条从原点到平面上某个点的线。 (即你有一个从原点到 vP1 的向量)。这个向量的问题在于它很可能是倾斜的,并且会到达飞机上的某个较远的地方,而不是飞机上最近的点。所以,如果你只是简单地取 vP1 的长度,你会得到一个太大的距离。

    您需要做的是将 vP1 投影到您知道垂直于平面的某个向量上。那当然是 vNormal。所以取 vP1 和 vNormal 的点积,然后除以 vNormal 的长度,你就有了答案。 (如果他们好心给你一个已经是 1 级的 vNormal,那么就不需要除法了。)

    【讨论】:

      【解决方案3】:

      你可以用拉格朗日乘数来解决这个问题:

      你知道平面上最近的点一定是这样的:

      c = p + v
      

      其中c 是最近点,v 是沿平面的向量(因此与法线n 正交)。您正在尝试找到具有最小范数(或范数平方)的c。所以你试图最小化dot(c,c),以使vn正交(因此dot(v,n) = 0)。

      因此,设置拉格朗日:

      L = dot(c,c) + lambda * ( dot(v,n) )
      L = dot(p+v,p+v) + lambda * ( dot(v,n) )
      L = dot(p,p) + 2*dot(p,v) + dot(v,v) * lambda * ( dot(v,n) )
      

      v(并设置为0)求导得到:

      2 * p + 2 * v + lambda * n = 0
      

      您可以通过在上面的等式中通过在n 的两边点积来解决 lambda

      2 * dot(p,n) + 2 * dot(v,n) + lambda * dot(n,n) = 0
      2 * dot(p,n) + lambda = 0
      lambda = - 2 * dot(p,n)
      

      再次注意dot(n,n) = 1dot(v,n) = 0(因为v 在平面内,而n 与其正交)。然后将lambda 代入以获取:

      2 * p + 2 * v - 2 * dot(p,n) * n = 0
      

      求解v得到:

      v = dot(p,n) * n - p
      

      然后将其插入c = p + v 以获取:

      c = dot(p,n) * n
      

      这个向量的长度是|dot(p,n)|,符号告诉你这个点是在原点的法向量方向,还是从原点的反方向。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-27
        相关资源
        最近更新 更多