如何找到关于某个坐标的曲面的最近点?
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_points
的 y
值。我的意思是,对于第一点,我想要创建表面的最接近点,它的 y
值为 1
。为简单起见,我只复制了它们的 y
值等于我的平面的 brders 的数据,实际上我可能在平面的 brders 之间有其他具有 y
值的点,但我仍然想找到投影具有固定的 y
值。我尝试了以下方法,但它只是给我一个表面的水平投影,我不能处理两个表面(当 surf_corners
和 surrounding_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
值的最近点)。提前,我很感激任何帮助。
我了解到您需要解决以下问题:
- 给定四个 3D 点形成一个平面四边形,确定这些点所在的平面。
- 将任意 3D 点投影到平面上。
- 检查投影点是否在四边形内。
问题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.
中描述的优化
我在 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_points
的 y
值。我的意思是,对于第一点,我想要创建表面的最接近点,它的 y
值为 1
。为简单起见,我只复制了它们的 y
值等于我的平面的 brders 的数据,实际上我可能在平面的 brders 之间有其他具有 y
值的点,但我仍然想找到投影具有固定的 y
值。我尝试了以下方法,但它只是给我一个表面的水平投影,我不能处理两个表面(当 surf_corners
和 surrounding_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
值的最近点)。提前,我很感激任何帮助。
我了解到您需要解决以下问题:
- 给定四个 3D 点形成一个平面四边形,确定这些点所在的平面。
- 将任意 3D 点投影到平面上。
- 检查投影点是否在四边形内。
问题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.
中描述的优化