我在表面上有一些点(对此我没有数学公式)。
我有一种算法可以给我表面的法线向量(实际上是给我点的那个算法),但是不幸的是,法线向量没有“对齐”。
我的意思是说,返回正常向量n
的算法会任意返回n
或-n
。先验先知,我无从得知。这不一定是问题,但是我的矢量场图看起来很糟糕,因为彼此相邻的两个点可能具有指向相反方向的矢量。因此,我想“对齐”我的法向矢量,因为我希望它们中的大多数都能反映对象的相同方向(即,所有点都“向外”或所有点都“向内”)>
我认识到没有完美的公式,但是我很难开发出一种算法,该算法甚至可以做得很好。
我当前的算法采用与当前算法最接近的k
点,确定当前法线向量与这些k
点处的法线对齐的程度(通过点积),取其平均值,以及它与邻居“不对齐”,翻转向量。我重复了此过程几次,以允许不同点的邻域之间进行交互。
这是到目前为止的代码:
import sklearn.neighbors
import numpy as np
def align_normals(data, normals, k=10, iterations=10):
balltree = sklearn.neighbors.BallTree(data)
pairwise_nearest_indices = balltree.query(data,k=k,sort_results=True,return_distance=False)
for iteration in range(iterations):
alignments = []
for index in range(1,pairwise_nearest_indices.shape[1]):
alignment = np.einsum("ij,ij->i",normals,normals[pairwise_nearest_indices[:,index]])
alignments.append(alignment)
alignment = np.average(alignments, axis=0)
wrong_alignment = np.sign(alignment)
normals = normals*wrong_alignment.reshape(-1,1)
return normals
在我看来,指向表面“末端”的点很容易对齐以向外指向,然后反复进行工作以使向量靠近这些点。但是,到目前为止,我的所有想法似乎都是废话。
有人对对齐法向矢量有什么好主意吗?