如何在 3D 坐标列表中查找单独的对象
How to find separate objects in a list of 3D coordinates
我开始尝试编写一个基本的体素类型脚本,它会在与一个点相邻的 6 个方向上寻找 n 在任何一侧画一个平面,它旁边没有任何东西。然后我可以组合这些平面,它会成为一个对象。
这在所有对象都是一个对象时效果很好,但如果对象之间存在 space,它仍会将所有对象合并为一个对象。由于坐标列表类似于 (x,y,z)
,我将如何根据连接的内容拆分它?我能想到的唯一方法是处理量很大,并且会涉及在构建对象时检查对象周围的每个空闲 space,直到剩下 none,但我想可能应该有更好的方法.
郑重声明,这实际上不会用于任何用途,只是为了好玩,看看我是否可以做到
import pymel.core as py
directions = [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]]
grid = {}
grid[(0,0,0)] = 1
grid[(1,0,0)] = 0
grid[(-1,0,0)] = 1
grid[(0,1,0)] = 1
for originalCoordinate in grid.keys():
adjacentCoordinates = [tuple( sum( j ) for j in zip( i, originalCoordinate ) ) for i in directions]
blockHere = grid[originalCoordinate]
if blockHere:
for newCoordinate in adjacentCoordinates:
if not grid.get( newCoordinate, 0 ):
newDirection = tuple( i[1]-i[0] for i in zip( originalCoordinate, newCoordinate ) )
newSide = py.polyPlane( width = 1, height = 1, sx = 1, sy = 1 )[0]
sideLocation = list( originalCoordinate )
sideRotation = [0, 0, 0]
if newDirection[0]:
if newDirection[0] > 0:
print originalCoordinate, "Facing X"
sideLocation[0] += 0.5
sideRotation[2] += -90
else:
print originalCoordinate, "Facing -X"
sideLocation[0] += -0.5
sideRotation[2] += 90
if newDirection[1]:
if newDirection[1] > 0:
print originalCoordinate, "Facing Y"
sideLocation[1] += 0.5
sideLocation[1] += 0
else:
print originalCoordinate, "Facing -Y"
sideLocation[1] += -0.5
sideLocation[1] += 180
if newDirection[2]:
if newDirection[2] > 0:
sideLocation[2] += 0.5
sideRotation[0] += 90
print originalCoordinate, "Facing Z"
else:
sideLocation[2] += -0.5
sideRotation[0] += -90
print originalCoordinate, "Facing -Z"
py.move( newSide, sideLocation )
py.rotate( newSide, sideRotation )
像这样搜索 3-d 规则网格的常用方法是 octree。基本思想是将 space 分成二次方的立方体:每个立方体变成 8 个一半大小的小立方体,并报告其子物体中存在的物体。通过以这种方式递归细分,您可以快速消除对世界上大片空白区域的检查。实现起来并不难,因为它基本上是递归的:如果你让它适用于两个级别的细分,你就有能力根据需要进行更深入的细分。 github 上有几个 python 实现可供查看,我没有推荐一个。
我开始尝试编写一个基本的体素类型脚本,它会在与一个点相邻的 6 个方向上寻找 n 在任何一侧画一个平面,它旁边没有任何东西。然后我可以组合这些平面,它会成为一个对象。
这在所有对象都是一个对象时效果很好,但如果对象之间存在 space,它仍会将所有对象合并为一个对象。由于坐标列表类似于 (x,y,z)
,我将如何根据连接的内容拆分它?我能想到的唯一方法是处理量很大,并且会涉及在构建对象时检查对象周围的每个空闲 space,直到剩下 none,但我想可能应该有更好的方法.
郑重声明,这实际上不会用于任何用途,只是为了好玩,看看我是否可以做到
import pymel.core as py
directions = [[1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1]]
grid = {}
grid[(0,0,0)] = 1
grid[(1,0,0)] = 0
grid[(-1,0,0)] = 1
grid[(0,1,0)] = 1
for originalCoordinate in grid.keys():
adjacentCoordinates = [tuple( sum( j ) for j in zip( i, originalCoordinate ) ) for i in directions]
blockHere = grid[originalCoordinate]
if blockHere:
for newCoordinate in adjacentCoordinates:
if not grid.get( newCoordinate, 0 ):
newDirection = tuple( i[1]-i[0] for i in zip( originalCoordinate, newCoordinate ) )
newSide = py.polyPlane( width = 1, height = 1, sx = 1, sy = 1 )[0]
sideLocation = list( originalCoordinate )
sideRotation = [0, 0, 0]
if newDirection[0]:
if newDirection[0] > 0:
print originalCoordinate, "Facing X"
sideLocation[0] += 0.5
sideRotation[2] += -90
else:
print originalCoordinate, "Facing -X"
sideLocation[0] += -0.5
sideRotation[2] += 90
if newDirection[1]:
if newDirection[1] > 0:
print originalCoordinate, "Facing Y"
sideLocation[1] += 0.5
sideLocation[1] += 0
else:
print originalCoordinate, "Facing -Y"
sideLocation[1] += -0.5
sideLocation[1] += 180
if newDirection[2]:
if newDirection[2] > 0:
sideLocation[2] += 0.5
sideRotation[0] += 90
print originalCoordinate, "Facing Z"
else:
sideLocation[2] += -0.5
sideRotation[0] += -90
print originalCoordinate, "Facing -Z"
py.move( newSide, sideLocation )
py.rotate( newSide, sideRotation )
像这样搜索 3-d 规则网格的常用方法是 octree。基本思想是将 space 分成二次方的立方体:每个立方体变成 8 个一半大小的小立方体,并报告其子物体中存在的物体。通过以这种方式递归细分,您可以快速消除对世界上大片空白区域的检查。实现起来并不难,因为它基本上是递归的:如果你让它适用于两个级别的细分,你就有能力根据需要进行更深入的细分。 github 上有几个 python 实现可供查看,我没有推荐一个。