如何找到关于某个坐标的曲面的最近点?

How to find the closest points of a surface regarding some coordinate?

我在 3d space(x、y 和 z)中有一堆点,想找到点之间存在的最近的表面点。我阅读了 this solution 但无法解决我的问题。我的表面是由四个点创建的,使用:

PRECISION = 1e-8    # Arbitrary zero for real-world purposes
def plane_from_points(points):
    centroid = np.mean(points, axis=0)
    _, eigenvalues, eigenvectors = np.linalg.svd(points - centroid)
    if eigenvalues[1] < PRECISION:
        raise ValueError("Points are aligned, can't define a plane")
    normal = eigenvectors[2]
    d = -np.dot(centroid, normal)
    plane = np.append(normal, d)
    thickness = eigenvalues[2]
    return plane, thickness

我的点之间有一个倾斜的(在我的图中用黑点显示)和一个正常的(用黄点显示)表面。表面的角是:

surf_corners=[np.array([[1., 1., 1.], [1.5, 2., 1.], [3., 1., 3.], [3.5, 2., 3.]]),\
              np.array([[5., 1., 4.], [5., 2., 4.], [7., 1., 2.], [7., 2., 2.]])]

第一排是倾斜的,第二排是正常的。这些是我想要找到表面的壁橱点的点:

surrounding_points=[np.array([[2., 1., 3.2], [3., 2., 3.]]),\
                    np.array([[6., 1., 2.5], [6., 2., 2.5], [6., 1., 3.5], [6., 2., 3.5]])]

surrounding_points 的第一个数组(蓝色方块所示)的投影应该在 surf_corners 的第一个数组和第二个数组(红色方块所示)创建的表面上找到第二个表面。我的表面应该只在它的四个角之间,而不是无穷大。我的意思是计算点的 y 值不应小于或大于角点。例如,我更喜欢维护 surrounding_pointsy 值。我的意思是,对于第一点,我想要创建表面的最接近点,它的 y 值为 1。为简单起见,我只复制了它们的 y 值等于我的平面的 brders 的数据,实际上我可能在平面的 brders 之间有其他具有 y 值的点,但我仍然想找到投影具有固定的 y 值。我尝试了以下方法,但它只是给我一个表面的水平投影,我不能处理两个表面(当 surf_cornerssurrounding_points ar numpy 数组而不是 numpy 数组列表时) :

pls=[]
for i in surf_corners:
    i=i.tolist()
    pl, thickness= plane_from_points(i)
    pls.append(pl)
point_on_surf=[]
n_iter=1
for i in range (n_iter):
    a, b, c, d = pls[i][0], pls[i][1], pls[i][2], pls[i][3]
    def fun(row):
        row[0] = -(d + b * row[1] + c * row[2]) / a # calculates new x
        return row[0], row[1], row[2] # new x and old y and z
    to_be_projected=[copy.copy(surrounding_points[i])]
    new_points = np.asarray(list(map(fun, [x for point in to_be_projected for x in point])))
    point_on_surf.append(new_points)

为了更清楚,我上传了一张图。绿色箭头显示我想要的投影点(具有相同 y 值的最近点)。提前,我很感激任何帮助。

我了解到您需要解决以下问题:

  1. 给定四个 3D 点形成一个平面四边形,确定这些点所在的平面。
  2. 将任意 3D 点投影到平面上。
  3. 检查投影点是否在四边形内。

问题1.确定平面

我了解到您正在使用 中的代码,所以我不会再发表评论了。

问题2.投影一个点

您可以使用

计算投影点
projected_point = p - np.dot(p - p0, u) * u

哪里

  • p是项目的重点
  • p0是平面上的一个点(定义四边形的点之一,它们的质心...)
  • u为平面的单位法向量

编辑:


平面计算方法只要提供平面系数(a,b,c,d) 其中(a,b,c)是平面的法向量,也是单位向量,就可以计算出投影使用:

u = plane[:3]                      # Plane's normal unit vector
d = plane[3]                       # Signed distance plane - origin of coordinates
distance = np.dot(u, point) + d    # Signed distance point - plane
projected_point = point - distance * u

问题3.四边形内的点

我建议使用 winding number 方法。而且,如果您知道您的四边形是凸的,您可以利用相同 link.

中描述的优化