首页 > 解决方案 > 通过邻域中的样本计算 3D 点的法线

问题描述

我遇到了一个问题,我有一个 3D 对象,我只能使用小的线性线对其进行采样。对于该对象的给定点,我想找到相应的法线向量。

因此,通过使用 3D 线条,我在邻域中搜索更多采样点。对于通过采样找到的那些邻居,我想以创建三角剖分的方式近似法线,其中每个三角形都使用中心点。平均法线将是输出。

这是一些采样线可以放在研究点周围的方式: 在此处输入图像描述

另一个带有更多采样线的示例。

3

有谁知道如何找到一个稳定的三角测量或有一个有前途的想法?

标签: algorithmmathvectorsamplingtriangulation

解决方案


如果您不太关心速度,您可以按ang = atan2(a,b,n)角度对相邻点进行排序:

n   - view direction
ang - CW? angle

sin(ang) = ((n x a).b)/(|a|*|b|)
cos(ang) = (a.b)      /(|a|*|b|)

if (sin(ang)>=0) ang=       acos(cos(ang))
if (sin(ang)< 0) ang=2*Pi - acos(cos(ang))
ang = <0,2*Pi)

因此,如果您有点p0及其邻居p1,p2,p3,...,则例如将视图向量设置为:

n = (p1-p0) x (p2-p1)
n = n / |n|

然后计算每个点的角度

a1 = 0
a2 = atan2(p1-p0,p2-p0,n)
a3 = atan2(p1-p0,p3-p0,n)
...

然后简单地按它们的角度对点 p1,p2,... 进行排序,然后您可以简单地进行三角剖分(作为使用 p0 作为扇形基点的三角形扇形)...

triangle(q0,q1,q2)
triangle(q0,q2,q3)
triangle(q0,q3,q4)
...

排序顺序q0,q1,q2,q3...的点在哪里p0,p1,p2,p3,...

从这里你可以简单地应用你的正常计算......还要检查这个:

如果您想按三角形大小对法线进行加权,那么就不要对部分法线进行归一化,而只需对结果和法线进行归一化,而不是将其除以cnt...

顺便说一句,这也可以在没有任何测角学的情况下完成……您可以使用冒泡排序并简单地对它们的点进行排序,以便遵守选定的缠绕规则,例如:

if (dot(n,cross(p(i)-p0,p(j)-p0)) > 0) swap(p(i),p(j))

然而,这将阻止使用更快的排序算法,因此除非使用点的一些空间细分,否则对于太多的点来说会很慢......对于空间细分或少量的点,这应该很快。此外,这种方法不需要任何额外的内存空间,因为不需要角度并且可以就地进行排序。


推荐阅读