private void TransformVonNeumann() { // Transformação usando vizinhança Von Neumann int topX = SoilMap.GetLength(0); int topY = SoilMap.GetLength(1); float[,] baseHeights = SoilMap.Clone() as float[, ]; // Loop geral do mapa for (int x = 0; x < SoilMap.GetLength(0); x++) { for (int y = 0; y < SoilMap.GetLength(1); y++) { // Fazer a média da altura com base nos vizinhos float sumHeights = 0.0f; int countHeights = 0; // Primeiro somar os vizinhos na horizontal for (int relX = -Configs.Range; relX <= Configs.Range; relX++) { int absX = x + relX; if (absX < 0 || absX >= topX) { continue; } sumHeights += baseHeights[absX, y]; countHeights++; } // Depois na vertical for (int relY = -Configs.Range; relY <= Configs.Range; relY++) { int absY = y + relY; if (absY < 0 || absY >= topY) { continue; } sumHeights += baseHeights[x, absY]; countHeights++; } // Subtrair o valor da célula central que foi somado duas vezes sumHeights -= baseHeights[x, y]; countHeights--; // Aplicar a média dos valores if (countHeights > 0) { float diff = (sumHeights / countHeights) - SoilMap[x, y]; SoilMap[x, y] += diff * Configs.Factor; } } } }
private void TransformMoore() { // Transformação usando vizinhança Moore int topX = SoilMap.GetLength(0); int topY = SoilMap.GetLength(1); float[,] baseHeights = SoilMap.Clone() as float[, ]; // Loop geral do mapa for (int x = 0; x < SoilMap.GetLength(0); x++) { for (int y = 0; y < SoilMap.GetLength(1); y++) { // Fazer a média da altura com base nos vizinhos float sumHeights = 0.0f; int countHeights = 0; // Loop interno dos vizinhos for (int relX = -Configs.Range; relX <= Configs.Range; relX++) { int absX = x + relX; if (absX < 0 || absX >= topX) { continue; } for (int relY = -Configs.Range; relY <= Configs.Range; relY++) { int absY = y + relY; if (absY < 0 || absY >= topY) { continue; } sumHeights += baseHeights[absX, absY]; countHeights++; } } // Aplicar a média dos valores if (countHeights > 0) { float diff = (sumHeights / countHeights) - SoilMap[x, y]; SoilMap[x, y] += diff * Configs.Factor; } } } }
public override void ApplyTransform() { int topX = SoilMap.GetLength(0); int topY = SoilMap.GetLength(1); float[,] baseHeights = SoilMap.Clone() as float[, ]; float[,] heightDiff = new float[topX, topY]; for (int x = 0; x < SoilMap.GetLength(0); x++) { for (int y = 0; y < SoilMap.GetLength(1); y++) { // Fazer a média da altura com base nas alturas vizinhas // Apenas considerar variação para baixo float sumHeights = 0.0f; int countHeights = 0; for (int relX = -1; relX <= 1; relX++) { int absX = x + relX; if (absX < 0 || absX >= topX) { break; } for (int relY = -1; relY <= 1; relY++) { int absY = y + relY; if (absY < 0 || absY >= topY) { break; } sumHeights += baseHeights[absX, absY]; countHeights++; } } if (countHeights > 0) { float avg = sumHeights / countHeights; if (avg < SoilMap[x, y]) { SoilMap[x, y] = avg; heightDiff[x, y] = baseHeights[x, y] - avg; } } } } // Distribuir a massa de terra removida para os terrenos mais baixos for (int x = 0; x < SoilMap.GetLength(0); x++) { for (int y = 0; y < SoilMap.GetLength(1); y++) { int countLowLands = 0; // Quantidade de nodos mais baixos for (int relX = -1; relX <= 1; relX++) { int absX = x + relX; if (absX < 0 || absX >= topX) { break; } for (int relY = -1; relY <= 1; relY++) { int absY = y + relY; if (absY < 0 || absY >= topY) { break; } if (absX != x && absY != y && SoilMap[absX, absY] <= SoilMap[x, y]) { countLowLands++; } } } // Distribuição if (countLowLands > 0) { float depositPerPlot = heightDiff[x, y] / countLowLands; for (int relX = -1; relX <= 1; relX++) { int absX = x + relX; if (absX < 0 || absX >= topX) { break; } for (int relY = -1; relY <= 1; relY++) { int absY = y + relY; if (absY < 0 || absY >= topY) { break; } if (absX != x && absY != y && SoilMap[absX, absY] <= SoilMap[x, y]) { SoilMap[absX, absY] += depositPerPlot; } } } } else { SoilMap[x, y] += heightDiff[x, y]; } } } }
public void ApplyVonNeumann() { Directions direction = Configs.WindDirection; int topX = SoilMap.GetLength(0); int topY = SoilMap.GetLength(1); float[,] baseHeights = SoilMap.Clone() as float[, ]; for (int x = 0; x < SoilMap.GetLength(0); x++) { for (int y = 0; y < SoilMap.GetLength(1); y++) { float sumHeights = 0.0f; int countHeights = 0; // Direções horizontais if (direction == Directions.East || direction == Directions.West) { int from = direction == Directions.East ? -Configs.Range : 0; int to = direction == Directions.East ? 0 : Configs.Range; // Todos os vizinhos verticais for (int relX = -Configs.Range; relX <= Configs.Range; relX++) { int absX = x + relX; if (absX < 0 || absX >= topX) { continue; } sumHeights += baseHeights[absX, y]; countHeights++; } // Metade dos vizinhos horizontais for (int relY = from; relY <= to; relY++) { int absY = y + relY; if (absY < 0 || absY >= topY) { continue; } sumHeights += baseHeights[x, absY]; countHeights++; } // Subtrair o valor da célula central que foi somado duas vezes sumHeights -= baseHeights[x, y]; countHeights--; } // Direções verticais if (direction == Directions.North || direction == Directions.South) { int from = direction == Directions.North ? -Configs.Range : 0; int to = direction == Directions.North ? 0 : Configs.Range; // Metade dos vizinhos verticais for (int relX = from; relX <= to; relX++) { int absX = x + relX; if (absX < 0 || absX >= topX) { continue; } sumHeights += baseHeights[absX, y]; countHeights++; } // Todos os vizinhos horizontais for (int relY = -Configs.Range; relY <= Configs.Range; relY++) { int absY = y + relY; if (absY < 0 || absY >= topY) { continue; } sumHeights += baseHeights[x, absY]; countHeights++; } // Subtrair o valor da célula central que foi somado duas vezes sumHeights -= baseHeights[x, y]; countHeights--; } // Direções diagonais else { int fromX = 0; int fromY = 0; int toX = 0; int toY = 0; // Selecionar valores para representar a diagonal selecionada switch (direction) { case Directions.Northeast: fromX = -Configs.Range; fromY = -Configs.Range; break; case Directions.Southeast: toX = Configs.Range; fromY = -Configs.Range; break; case Directions.Southwest: toX = Configs.Range; toY = Configs.Range; break; case Directions.Northwest: fromX = -Configs.Range; toY = Configs.Range; break; } // Vizinhos verticais for (int relX = fromX; relX <= toX; relX++) { int absX = x + relX; if (absX < 0 || absX >= topX) { continue; } sumHeights += baseHeights[absX, y]; countHeights++; } // Vizinhos horizontais for (int relY = fromY; relY <= toY; relY++) { int absY = y + relY; if (absY < 0 || absY >= topY) { continue; } sumHeights += baseHeights[x, absY]; countHeights++; } // Subtrair o valor da célula central que foi somado duas vezes sumHeights -= baseHeights[x, y]; countHeights--; } // Aplicar média if (countHeights > 0) { float avg = sumHeights / countHeights; if (avg < SoilMap[x, y]) { float diff = avg - SoilMap[x, y]; SoilMap[x, y] += diff * Configs.Factor; } } } } }
public void ApplyMoore() { int topX = SoilMap.GetLength(0); int topY = SoilMap.GetLength(1); float[,] baseHeights = SoilMap.Clone() as float[, ]; int startX = GetStartingX(); int startY = GetStartingY(); int endX = GetEndingX(); int endY = GetEndingY(); int incStartY = GetStartingYIncrement(); int incEndY = GetEndingYIncrement(); for (int x = 0; x < SoilMap.GetLength(0); x++) { for (int y = 0; y < SoilMap.GetLength(1); y++) { // Fazer a média da altura com base nas alturas vizinhas no hemisfério Sul // Apenas considerar alterações para baixo float sumHeights = 0.0f; int countHeights = 0; int localStartY = startY; int localEndY = endY; for (int relX = startX; relX <= endX; relX++) { int absX = x + relX; if (absX < 0 || absX >= topX) { continue; } for (int relY = localStartY; relY <= localEndY; relY++) { int absY = y + relY; if (absY < 0 || absY >= topY) { continue; } sumHeights += baseHeights[absX, absY]; countHeights++; } localStartY += incStartY; localEndY += incEndY; } if (countHeights > 0) { float avg = sumHeights / countHeights; if (avg < SoilMap[x, y]) { float diff = avg - SoilMap[x, y]; SoilMap[x, y] += diff * Configs.Factor; } } } } }