所以我正在阅读这个页面上的内容(http://gamedeveloperjourney.blogspot.com/2009/04/point-plane-collision-detection.html)
作者提到
d = - D3DXVec3Dot(&vP1, &vNormal);其中vP1是平面上的点,vNormal是平面的法线。我很好奇这是如何得到与世界原点的距离的,因为结果总是0。另外,为了清楚(因为我对平面方程的d部分还不太清楚),平面方程中的d是不是从世界原点的直线到平面原点的距离?
发布于 2011-12-17 05:52:08
在一般情况下,点p和平面之间的距离可以由下式计算
<p - p0, normal>其中<a, b>是点积运算
<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)实际上,存储平面的一个很好的方法是保存正常的n和k = <p0, n>的值,其中p0是平面上的任意点( k的值与您在平面中选择的点无关)。
发布于 2011-12-19 05:19:55
结果并不总是为零。只有当平面经过原点时,结果才会为零。(在这里,我们假设飞机不经过原点。)
基本上,你会得到一条从原点到平面上某点的直线。(即,您有一个从原点到vP1的向量)。这个向量的问题是,它很可能是倾斜的,在平面上去的是很远的地方,而不是平面上最近的点。所以,如果你简单的取vP1的长度,你会得到一个太大的距离。
你需要做的是把vP1投影到某个向量上,你知道这个向量垂直于平面。这当然是vNormal。所以取vP1和vNormal的点积,除以vNormal的长度,你就得到了答案。(如果他们很友好地给了你一个已经是1级的vNormal,那么就不需要除法了。)
发布于 2011-12-17 06:14:11
你可以用拉格朗日乘数来解决这个问题:
你知道平面上最近的点必须是这样的:
c = p + v其中,c是最近的点,v是沿平面的向量(因此与法线n正交)。您正在尝试寻找具有最小范数(或范数平方)的c。因此,您正在尝试最小化dot(c,c),使v与n正交(因此是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对两边进行点生成来求解λby,以获得
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) = 1和dot(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)|,符号将告诉您该点是位于距原点的法线向量的方向上,还是位于距原点的相反方向上。
https://stackoverflow.com/questions/8540531
复制相似问题