如何利用Parallel.For迭代索引计算任意尺寸3D数组的三维坐标?
3D数组单Parallel.For循环的坐标转换问题
我有一个X、Y、Z长度任意的3D数组,想用Parallel.For循环遍历。听说嵌套Parallel.For会浪费任务,所以改用长度为ArrayLengthX * ArrayLengthY * ArrayLengthZ的单循环。请问能不能通过当前迭代次数结合数组的X、Y、Z长度,用数学方法得到对应的三维坐标?如果可以,具体怎么实现?
示例代码如下:
DimensionSettings dimensionSettings = dimension.Settings; Vector3Int DimSize = dimensionSettings.GetDimensionSize(); TaskProgressMutex.WaitOne(); CurrentProgress = 0; TotalProgress = DimSize.x * DimSize.y * DimSize.z; TaskProgressMutex.ReleaseMutex(); int ChunkAmount = DimSize.x * DimSize.y * DimSize.z; GD.Print("Chunks to generate : " + ChunkAmount); ParallelLoopResult result = Parallel.For(0, ChunkAmount, (int i) => { GD.Print(i); int xcoords = ???; int ycoords = ???; int zcoords = ???; Vector3Int ChunkCoords = new Vector3Int(xcoords, ycoords, zcoords); GD.Print("Current Chunk : " + xcoords + " " + ycoords + " " + zcoords); GenerateChunk(ChunkCoords, seed); TaskProgressMutex.WaitOne(); CurrentProgress += 1; //GD.Print("Chunk " + xcoords + " " + ycoords + " " + zcoords + " finished generating. Current Progress : " + CurrentProgress); TaskProgressMutex.ReleaseMutex(); });
实现方法
完全可以通过数学运算将一维迭代索引i转换为三维坐标,核心利用整除和取余运算拆分维度(以下逻辑基于行优先遍历顺序:先遍历X轴所有元素,再推进Y轴,最后推进Z轴):
- X坐标计算:
xcoords = i % DimSize.x
每次X轴遍历完一轮后,余数会重置为0,刚好对应X轴的起始位置,以此循环。 - Y坐标计算:
ycoords = (i / DimSize.x) % DimSize.y
先除以X轴长度,得到已完成的X轴循环次数,再对Y轴长度取余,即可得到当前Y轴的位置。 - Z坐标计算:
zcoords = i / (DimSize.x * DimSize.y)
除以X、Y轴长度的乘积,得到已完成的XY平面循环次数,也就是当前Z轴的位置。
修改后的完整代码
DimensionSettings dimensionSettings = dimension.Settings; Vector3Int DimSize = dimensionSettings.GetDimensionSize(); TaskProgressMutex.WaitOne(); CurrentProgress = 0; TotalProgress = DimSize.x * DimSize.y * DimSize.z; TaskProgressMutex.ReleaseMutex(); int ChunkAmount = DimSize.x * DimSize.y * DimSize.z; GD.Print("Chunks to generate : " + ChunkAmount); // 提前计算XY乘积,避免重复计算提升效率 int xyProduct = DimSize.x * DimSize.y; ParallelLoopResult result = Parallel.For(0, ChunkAmount, (int i) => { GD.Print(i); int xcoords = i % DimSize.x; int ycoords = (i / DimSize.x) % DimSize.y; int zcoords = i / xyProduct; Vector3Int ChunkCoords = new Vector3Int(xcoords, ycoords, zcoords); GD.Print("Current Chunk : " + xcoords + " " + ycoords + " " + zcoords); GenerateChunk(ChunkCoords, seed); TaskProgressMutex.WaitOne(); CurrentProgress += 1; TaskProgressMutex.ReleaseMutex(); });
内容的提问来源于stack exchange,提问作者PaperMartin
相关产品推荐
相关产品推荐

