algorithm - 通过邻域中的样本计算 3D 点的法线
问题描述
我遇到了一个问题,我有一个 3D 对象,我只能使用小的线性线对其进行采样。对于该对象的给定点,我想找到相应的法线向量。
因此,通过使用 3D 线条,我在邻域中搜索更多采样点。对于通过采样找到的那些邻居,我想以创建三角剖分的方式近似法线,其中每个三角形都使用中心点。平均法线将是输出。
这是一些采样线可以放在研究点周围的方式:
另一个带有更多采样线的示例。
有谁知道如何找到一个稳定的三角测量或有一个有前途的想法?
解决方案
如果您不太关心速度,您可以按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))
然而,这将阻止使用更快的排序算法,因此除非使用点的一些空间细分,否则对于太多的点来说会很慢......对于空间细分或少量的点,这应该很快。此外,这种方法不需要任何额外的内存空间,因为不需要角度并且可以就地进行排序。
推荐阅读
- jenkins - conn_id 未在 Airflow JenkinsJobTriggerOperator 中定义
- javascript - 如何在webgl中使用alpha绘制两个纹理
- python - searchpyi.py 的问题 - '用 Python 自动化无聊的东西'
- angular - Nested Observable/Promise (trying to block/wait flow in mapper function)
- java - “circle” Cannot be resolved to a variable
- python - 如何避免 yticks 或 xticks 被破坏
- java - 将图像作为子项添加到 StackPane(缩放问题)
- authentication - cakephp 4 Testing Actions That Require Authentication
- google-cloud-dataflow - Why is DataflowRunner putting some kind of hash value into the staged jars filename?
- mongodb - Query performance of a range query with date field