public TBetterCubeTraverse(TModel model) { R = model.R; LevelBorders = new List <TBorders>(); for (int y = 0; y < R; ++y) { TBorders thisLevelBorders = new TBorders(); for (int x = 0; x < R; ++x) { for (int z = 0; z < R; ++z) { if (model[x, y, z] > 0) { MaxY = Math.Max(MaxY, y); thisLevelBorders.MinX = Math.Min(thisLevelBorders.MinX, x); thisLevelBorders.MaxX = Math.Max(thisLevelBorders.MaxX, x); thisLevelBorders.MinZ = Math.Min(thisLevelBorders.MinZ, z); thisLevelBorders.MaxZ = Math.Max(thisLevelBorders.MaxZ, z); } } } LevelBorders.Add(thisLevelBorders); } }
public TDumpCubeTraverse(TModel srcModel, TModel dstModel) { R = srcModel.R; LevelBorders = new List <TBorders>(); for (var y = 0; y < R; ++y) { var thisLevelBorders = new TBorders(); for (var x = 0; x < R; ++x) { for (var z = 0; z < R; ++z) { if (srcModel[x, y, z] > 0 || dstModel[x, y, z] > 0) { MaxY = Math.Max(MaxY, y); thisLevelBorders.MinX = Math.Min(thisLevelBorders.MinX, x); thisLevelBorders.MaxX = Math.Max(thisLevelBorders.MaxX, x); thisLevelBorders.MinZ = Math.Min(thisLevelBorders.MinZ, z); thisLevelBorders.MaxZ = Math.Max(thisLevelBorders.MaxZ, z); } } } if (thisLevelBorders.MaxX == thisLevelBorders.MinX) { ++thisLevelBorders.MaxX; --thisLevelBorders.MinX; } if (thisLevelBorders.MaxZ == thisLevelBorders.MinZ) { ++thisLevelBorders.MaxZ; --thisLevelBorders.MinZ; } LevelBorders.Add(thisLevelBorders); } }
public TCoord Next(TModel model) { if (LetGoBack || Current.Y > MaxY + 1) { LetGoBack = true; return(NextForReturn()); } if (Current.Y == 0) { Direction.Dx = 0; Direction.Dy = 1; Direction.Dz = 0; Current.Apply(Direction); return(Current); } TBorders borders = LevelBorders[Current.Y - 1]; if (SearchStartPosition) { int targetX = (Current.Y % 2 == 1) ? borders.MinX : borders.MaxX; int targetZ = (Current.Y % 2 == 1) ? borders.MinZ : borders.MaxZ; if (Current.X < targetX) { Direction.Dx = Math.Min(15, targetX - Current.X); Direction.Dy = 0; Direction.Dz = 0; Current.Apply(Direction); return(Current); } if (Current.Z < targetZ) { Direction.Dx = 0; Direction.Dy = 0; Direction.Dz = Math.Min(15, targetZ - Current.Z); Current.Apply(Direction); return(Current); } if (Current.X > targetX) { Direction.Dx = Math.Max(-15, targetX - Current.X); Direction.Dy = 0; Direction.Dz = 0; Current.Apply(Direction); return(Current); } if (Current.Z > targetZ) { Direction.Dx = 0; Direction.Dy = 0; Direction.Dz = Math.Max(-15, targetZ - Current.Z); Current.Apply(Direction); return(Current); } SearchStartPosition = false; } if (Current.Y % 2 == 1) { if (Current.X > borders.MaxX && Current.Z > borders.MaxZ) // end of life { Direction.Dx = 0; Direction.Dy = 1; Direction.Dz = 0; SearchStartPosition = true; } else if (Current.X == borders.MinX && Current.Z == borders.MinZ) // walk forward X { Direction.Dx = 1; Direction.Dy = 0; Direction.Dz = 0; } else if (Direction.Dx > 0 && Current.X > borders.MaxX) // one step forward Z { Direction.Dx = 0; Direction.Dy = 0; Direction.Dz = 1; } else if (Direction.Dz > 0 && Current.X > borders.MaxX) // walk backward X { Direction.Dx = -1; Direction.Dy = 0; Direction.Dz = 0; } else if (Direction.Dx < 0 && Current.X < borders.MinX) // one step forward Z { Direction.Dx = 0; Direction.Dy = 0; Direction.Dz = 1; } else if (Direction.Dz > 0 && Current.X < borders.MinX) // walk again forward X { Direction.Dx = 1; Direction.Dy = 0; Direction.Dz = 0; } } else if (Current.Y % 2 == 0) { if (Current.X < borders.MinX && Current.Z < borders.MinZ) // end of life { Direction.Dx = 0; Direction.Dy = 1; Direction.Dz = 0; SearchStartPosition = true; } else if (Current.X == borders.MaxX && Current.Z == borders.MaxZ) // walk backward X { Direction.Dx = -1; Direction.Dy = 0; Direction.Dz = 0; } else if (Direction.Dx < 0 && Current.X < borders.MinX) // one step backward Z { Direction.Dx = 0; Direction.Dy = 0; Direction.Dz = -1; } else if (Direction.Dz < 0 && Current.X < borders.MinX) // walk forward X { Direction.Dx = 1; Direction.Dy = 0; Direction.Dz = 0; } else if (Direction.Dx > 0 && Current.X > borders.MaxX) // one step backward Z { Direction.Dx = 0; Direction.Dy = 0; Direction.Dz = -1; } else if (Direction.Dz < 0 && Current.X > borders.MaxX) // walk again backward X { Direction.Dx = -1; Direction.Dy = 0; Direction.Dz = 0; } } Current.Apply(Direction); return(Current); }