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框”?)@阿米特:我试图把语言简化一点——我希望这更容易理解。请让我知道这是否有意义-这是一个很难表达的问题。这是一个非常有趣的解决方案。所以,如果我错了,请纠正我,但是,每当没有更多可用的目标颜色,但节点尚未被遍历时,我需要重新播种,对吗?由于已知种子颜色,我会将其设置为每次种子遍历的目标颜色?正确,您需要迭代每个块,如果块尚未被淹没,则从该块开始对该颜色执行泛洪填充。