如何在3D平面上投射点?

Geo*_*rge 58 c c++

我有一个3D点(point_x,point_y,point_z),我想把它投影到3D空间的2D平面上,其中(平面)由点坐标(orig_x,orig_y,orig_z)和一元垂直向量(normal_dx)定义,normal_dy,normal_dz).

我该怎么处理?在此输入图像描述

tmp*_*rce 77

1)从你的orig观点到关注点制作一个矢量:

v = point-orig (in each dimension);

2)用单位法向量取该向量的点积n:

dist = vx*nx + vy*ny + vz*nz; dist =沿法线从点到平面的标量距离

3)将单位法向量乘以距离,并从您的点中减去该向量.

projected_point = point - dist*normal;

用图片编辑:我已经修改了你的图片了.红色是v; vdot normal=蓝色和绿色的长度(dist上图).蓝是normal*dist. Green = blue * -1:找到planar_xyz,从中开始point并添加绿色矢量.

在此输入图像描述

  • @valdo取决于您是否需要离飞机最近的距离或垂直点.我把他的帖子解释为想要最近点. (2认同)
  • 您需要结合“d”来获取从点到平面的垂直距离,否则您将假设平面穿过原点。 (2认同)

bob*_*obo 38

这是很容易,你需要做的就是找到垂直(简称这里|_)从点距离P的平面,然后翻译 P 用的垂直距离在正常的平面的方向.结果是翻译P坐在飞机上.

举个简单的例子(我们可以通过检查来验证):

设n =(0,1,0),P =(10,20,-5).

在此输入图像描述

投影点应为(10,10,-5).你可以通过检查看到Pproj是垂直于平面的10个单位,如果它在平面上,它将具有y = 10.

那么我们如何分析才能找到它呢?

平面方程是Ax + By + Cz + d = 0.该等式意味着"为了使点(x,y,z)在平面中,它必须满足Ax + By + Cz + d = 0".

对于上面绘制的平面,Ax + By + Cz + d = 0等式是多少?

该平面具有正常的n =(0,1,0).只需使用飞机已有的测试点即可找到d :

(0)x + (1)y + (0)z + d = 0
Run Code Online (Sandbox Code Playgroud)

点(0,10,0)在平面内.在上面插入,我们发现,d = -10.然后平面方程为0x + 1y + 0z - 10 = 0(如果简化,则得到y = 10).

一个很好的解释d是它说明了平面沿着法线平移所需垂直距离,让平面穿过原点.

无论如何,一旦我们有了d,我们可以通过以下等式找到任何点到飞机的距离:

在此输入图像描述

| _距离平面有3种可能的结果类别:

  • 0:完全在飞机上(几乎不会发生浮点不准确问题)
  • +1:> 0:飞机前方(正常方向)
  • -1:<0:后面的平面(正常对侧)

无论如何,

在此输入图像描述

您可以通过上图中的检查验证其是否正确

  • @bobobobo:你写“......只是_add_ -10......”让我真的很困惑。你_不明确地_将 __n__ ⋅ __p__ + _d_ 的结果乘以 -1,只是为了写 _add_ 而不是 _subtract_。:P 我花了一些时间来解释你的答案,所以我会为其他人总结一下。给定一个由法线 __n__ 和标量 _d_​​ 定义的平面,平面上最接近给定点 __p__ 的点 __p__' 可以通过以下公式找到: 1) __p__' = __p__ - (__n__ ⋅ __p__ + _d_) * __n__ 如果该平面是由法线 __n__ 和平面 __o__ 上的一个点定义,您建议使用:2) _d_ = -__n__ ⋅ __o__ (4认同)

Mr.*_*r.H 12

这个答案是对现有两个答案的补充.我的目的是展示@tmpearce和@bobobobo的解释如何归结为同样的事情,同时为那些仅仅想要复制最适合他们情况的方程式的人提供快速答案.

由正常n和点o定义的平面的方法

@tmpearce在答案中解释了这种方法.

给定平面上具有正常n和点o的平面的点正常定义,可以通过以下方式找到作为最接近给定点p的平面上的点的点p ' :

1)p '= p - (n ·(p - o))*n

由正常n和标量d定义的平面的方法

@bobobobo在回答中解释了这种方法.

给定由法线n和标量d定义的平面,点p ',即最接近给定点p的平面上的点,可以通过以下方式找到:

2)p '= p - (n · p + d)*n

相反,你有一个平面的点正常定义(平面由平面上的法线n和点o定义)@bobobobo建议找到d:

3)d = - ñö

并将其插入等式2中.这得到:

4)p '= p - (n · p - n · o)*n

关于差异的说明

仔细研究方程式1和4.通过比较它们,你会发现方程1使用n ·(p - o),其中方程式2使用n · p - n · o.这实际上是写下同一件事的两种方式:

5)n ·(p - o)= n · p - n · o = n · p + d

因此,人们可以选择将标量d解释为"预先计算".我将解释:如果一个平面的no是已知的,但是o仅用于计算n ·(p - o),我们也可以用nd定义平面,然后计算n · p + d,因为我们刚刚看到那是一回事.

另外,使用d进行编程有两个好处:

  1. 现在找到p '是一个更简单的计算,特别是对于计算机.相比:
    • 使用no:3次减法+3次乘法+ 2次加法
    • 使用nd:0减法+3次乘法+3次加法.
  2. 使用d将平面的定义限制为仅4个实数(3表示n + 1表示d),而不是6(3表示n + 3表示o).这节省了⅓记忆.

  • 嗨@M2tM。距离我写这个答案已经有一段时间了。⋅ 表示[点积](https://en.wikipedia.org/wiki/Dot_product)。用 * 我的意思是指示[叉积](https://en.wikipedia.org/wiki/Cross_product)。(后者对我来说也不是立即显而易见的,但可以从 __p__ 和 __p'__ 位于同一平面(其中 __n__ 是法线)的事实中推断出来。这意味着 __p'__ = __p__ + 一些向量 _orthogonal_ 到__n__。正交向量是叉积方向的提示。)为了将来的读者,我将答案中的任何 * 替换为 ×。感谢您的关注! (3认同)
  • @Mr.H 我们如何在标量和向量之间进行叉积?如果我没记错的话,叉积是在两个向量之间定义的?(https://en.wikipedia.org/wiki/Cross_product)等式。2 和 4 包含 (**n⋅p** + d) 和 (**n⋅p** - **n⋅o**),它们都是标量。难道是我理解错了? (3认同)

val*_*ldo 10

仅提供平面原点和法向量是不够的.这确实定义了3d平面,但是这并没有定义平面上的坐标系.

认为您可以围绕法线向量围绕其原点旋转平面(即将法线向量放在原点并"旋转").

但是,您可以找到投影点到原点的距离(显然对旋转不变).

从3d点减去原点.然后用正常方向做一个十字产品.如果您的法向量被归一化 - 结果向量的长度等于所需的值.

编辑

完整的答案需要额外的参数.比如说,您还提供了表示飞机上x轴的矢量.所以我们有向量nx.假设他们已经正常化了.

原点用O表示,你的3D点是p.

那么您的观点将通过以下方式进行预测:

x =(p - O)点x

y =(p - O)点(n交叉x)