我有一堆顶点。我想仅使用云中的顶点在顶点云周围镶嵌一个“外壳”,这样外壳大致符合顶点云的形状。
有一种简单的方法吗?我想我可以在球形参数化点云,然后“走”最外面的顶点来镶嵌云,但我不确定这是否会起作用。
我认为添加顶点是可以接受的,但“shell”的一般形状应该与顶点云的形状相匹配。
答案 0 :(得分:2)
我有一个适用于2D情况的算法。它很棘手,但可以将其推广到3D空间。基本思想是从最小表面(2D中的三角形或3D中的四面体)开始,并在遍历点阵列时分割每个边(面)。
2D算法(python。完整来源/演示:http://pastebin.com/jmwUt3ES)
编辑:这个演示非常有趣:http://pastebin.com/K0WpMyA3
def surface(pts):
center = pt_center(pts)
tx = -center[0]
ty = -center[1]
pts = translate_pts(pts, (tx, ty))
# tricky part: initialization
# initialize edges such that you have a triangle with the origin inside of it
# in 3D, this will be a tetrahedron.
ptA, ptB, ptC = get_center_triangle(pts)
print ptA, ptB, ptC
# tracking edges we've already included (triangles in 3D)
edges = [(ptA, ptB), (ptB, ptC), (ptC, ptA)]
# loop over all other points
pts.remove(ptA)
pts.remove(ptB)
pts.remove(ptC)
for pt in pts:
ptA = (0,0)
ptB = (0,0)
# find the edge that this point will be splitting
for (ptA, ptB) in edges:
if crossz(ptA, pt) > 0 and crossz(pt, ptB) > 0:
break
edges.remove((ptA, ptB))
edges.append((ptA, pt))
edges.append((pt, ptB))
# translate everything back
edges = [((ptA[0] - tx, ptA[1] - ty), (ptB[0] - tx, ptB[1] - ty)) for (ptA, ptB) in edges]
return edges
结果:
推广到3D
根据点云的大小和速度要求,您可能需要更加聪明地了解数据结构,以便更快地添加/删除。
答案 1 :(得分:0)
我会考虑一个“度量”函数f(x,y,z),它返回3D空间中任意点的标量值。应该以考虑给定点(x,y,z)是否在云的“内部”或“外部”的方式构造该函数。例如,这可以是从(x,y,z)到云中的每个点的平均矢量的长度,或者它可以是(x,y,z)的某个附近内的多个浊点。选择功能会影响最终结果。
使用此f(x,y,z),您可以使用marching cubes algorithm执行曲面细分,基本上为特定值构造f(x,y,z)的等值面。
答案 2 :(得分:0)
3D凸包(convex hull algorithm for 3d surface z = f(x, y))。
然后,对于每个最大面上的点,搜索云上最近的点并重新三角化该面以包括该点。
根据距离每个剩余面最近浊点的最大距离,或者最大剩余面的大小(长度/是?)重复“足够接近”
答案 3 :(得分:0)
您应该尝试3d Delaunay Triangulation。这将对点云进行细分,同时确保三维网格仅具有来自点云的顶点。 CGAL有两种对点云进行三角测量的实现 - delaunay和regular。常规版本使用描述here的想法对点进行三角测量。
如果您使用的是C ++,则可以使用它们的实现。如果没有,你仍然可以自己查看他们的代码来实现它(虽然这很复杂)。