Exemplo n.º 1
0
        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;
                    }
                }
            }
        }
Exemplo n.º 2
0
        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];
                    }
                }
            }
        }
Exemplo n.º 4
0
        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;
                        }
                    }
                }
            }
        }
Exemplo n.º 5
0
        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;
                        }
                    }
                }
            }
        }