Javascript 在由不同颜色的立方体组成的网格中,如何找到匹配的簇? 定义集群

Javascript 在由不同颜色的立方体组成的网格中,如何找到匹配的簇? 定义集群,javascript,algorithm,sorting,vector,three.js,Javascript,Algorithm,Sorting,Vector,Three.js,任何一组相同颜色的立方体,接触面平面,而不是其角 簇将形成一个实心几何形状 帮助将问题形象化 让我们假设这些乐高玩具中的每一个都是大的1x1单位 在一个简化的代码示例中,让我们看看由1x1x1立方体构成的2x2x2网格: var mesh = [ // First layer ( x, y, z ) new THREE.Vector3( 0, 0, 0 ), new THREE.Vector3( 0, 0, 1 ), new THREE.Vector3( 1, 0, 0

任何一组相同颜色的立方体,接触面平面,而不是其角

簇将形成一个实心几何形状

帮助将问题形象化 让我们假设这些乐高玩具中的每一个都是大的
1x1
单位

在一个简化的代码示例中,让我们看看由
1x1x1
立方体构成的
2x2x2
网格:

var mesh = [ 

  // First layer   ( x, y, z )
  new THREE.Vector3( 0, 0, 0 ),
  new THREE.Vector3( 0, 0, 1 ),
  new THREE.Vector3( 1, 0, 0 ),
  new THREE.Vector3( 1, 0, 1 )

  //Second layer   ( x, y, z )
  new THREE.Vector3( 0, 1, 0 ),
  new THREE.Vector3( 0, 1, 1 ),
  new THREE.Vector3( 1, 1, 0 ),
  new THREE.Vector3( 1, 1, 1 )
];

网格中的每个立方体都有一种颜色:

//Indexes of mesh array sorted by color
var colors = {
  red: [0, 1, 4, 6],
  green: [2, 3, 5, 7]
}
这可以通过以下方法解决。Wikipedia页面在两个方面具有指导意义:

Flood-fill (node, target-color, replacement-color):
 1. If target-color is equal to replacement-color, return.
 2. If the color of node is not equal to target-color, return.
 3. Set the color of node to replacement-color.
 4. Perform Flood-fill (one step to the south of node, target-color, replacement-color).
    Perform Flood-fill (one step to the north of node, target-color, replacement-color).
    Perform Flood-fill (one step to the west of node, target-color, replacement-color).
    Perform Flood-fill (one step to the east of node, target-color, replacement-color).
 5. Return.

通过观察两个单元的距离为1时相邻,或者更简单地说,如果它们在一个维度上相差1,则可以将其扩展到三维,因此可以迭代所有六个相邻单元,而不是二维的四个相邻单元。

以下是使用我的npm包的网格的工作示例:

// It's easier to use floodFill if you represent your mesh as nested arrays:
var mesh = [
  [
    // 0,0,0  0,0,1
    ["red", "red"],

    // 0,1,0  0,1,1
    ["red", "green"],
  ],
  [
    // 1,0,0  1,0,1
    ["green", "green"],

    // 1,1,0  1,1,1
    ["red", "green"]
  ]
];

var redFill = floodFill({
  getter: function (x, y, z) { return mesh[x][y][z] },
  seed: [0, 0, 0]
});

var greenFill = floodFill({
  getter: function (x, y, z) { return mesh[x][y][z] },
  seed: [1, 1, 1]
});

console.log("redFill: " + JSON.stringify(redFill.flooded));
// redFill: [[0,0,0],[0,1,0],[1,1,0],[0,0,1]]

console.log("greenFill: " + JSON.stringify(greenFill.flooded));
// greenFill: [[1,1,1],[1,0,1],[1,0,0],[0,1,1]]
如果要使用其他表示,可以编写不同的
getter


如您所见,您需要为每个要填充的区域运行
floodFill
。要查找网格的所有区域,可以从每个可能的起始坐标运行
floodFill
,但已包含在其中一个泛洪区域中的坐标除外。这将是相当有效的,但可能有更复杂的方法可以在一次过程中找到所有区域。

你能解释一下你的
类型图
是什么意思,你所说的“立方体接触面”是什么意思,以及这里向量的相关性是什么(它不总是一个“3d框”?)@阿米特:我试图把语言简化一点——我希望这更容易理解。请让我知道这是否有意义-这是一个很难表达的问题。这是一个非常有趣的解决方案。所以,如果我错了,请纠正我,但是,每当没有更多可用的目标颜色,但节点尚未被遍历时,我需要重新播种,对吗?由于已知种子颜色,我会将其设置为每次种子遍历的目标颜色?正确,您需要迭代每个块,如果块尚未被淹没,则从该块开始对该颜色执行泛洪填充。