Перлин шумовой глюк - PullRequest
1 голос
/ 11 марта 2020

У меня есть бесконечный генератор карт. Хорошо работает с положительными координатами. Генерация положительных координат 1

Но по отрицательным координатам у меня есть эта тра sh: Прерванная генерация отрицательных координат 2

void generateChunk(int x0, int y0) {
    Chunk chunk = new Chunk(x0, y0);
    for(int yTile = 0; yTile < Chunk.CHUNK_SIZE; yTile++) {
        for(int xTile = 0; xTile < Chunk.CHUNK_SIZE; xTile++) {

            int pX = chunk.x0 + xTile;
            int pY = chunk.y0 + yTile;

            double perlinNoiseHeight = floorPerlinNoise.getHeight(pX, pY);;

            if(perlinNoiseHeight > BEACH_AREA) {
                chunk.setFloor(GrassTile.ID, xTile, yTile);
            } else if(perlinNoiseHeight > 0) {
                chunk.setFloor(SandTile.ID, xTile, yTile);
            } else {
                chunk.setFloor(WaterTile.ID, xTile, yTile);
            }
        }
    }
    saveChunk(chunk);
}

Класс шума Perlin:

package org.ixnomad.game.level.generation;

public class PerlinNoise {

    private double persistence, frequency, amplitude;
    private int octaves;
    private long seed;

    public PerlinNoise(double persistence, double frequency, double amplitude, int octaves, long seed) {
        this.persistence    = persistence;
        this.amplitude      = amplitude;
        this.frequency      = frequency;
        this.octaves        = octaves;
        this.seed           = seed;
    }

    public double getHeight(double x, double y) {
        return amplitude * total(x, y) + 0.4;
    }

    private double total(double i, double j) {
        double total = 0.0d;
        double _ampl = 1;
        double _freq = frequency;
        for(int k = 0; k < octaves; k++) {
            total += getValue(j * _freq + seed, i * _freq + seed) * _ampl;
            _ampl *= persistence;
            _freq *= 2;
        }
        return total;
    }

    private double getValue(double x, double y) {
        int xInt = (int) x;
        int yInt = (int) y;
        double xFrac = x - xInt;
        double yFrac = y - yInt;

        double n01 = noise(xInt-1, yInt-1);
        double n02 = noise(xInt+1, yInt-1);
        double n03 = noise(xInt-1, yInt+1);
        double n04 = noise(xInt+1, yInt+1);
        double n05 = noise(xInt-1, yInt  );
        double n06 = noise(xInt+1, yInt  );
        double n07 = noise(xInt  , yInt-1);
        double n08 = noise(xInt  , yInt+1);
        double n09 = noise(xInt  , yInt  );

        double n12 = noise(xInt+2, yInt-1);
        double n14 = noise(xInt+2, yInt+1);
        double n16 = noise(xInt+2, yInt  );

        double n23 = noise(xInt-1, yInt+2);
        double n24 = noise(xInt+1, yInt+2);
        double n28 = noise(xInt  , yInt+2);

        double n34 = noise(xInt+2, yInt+2);

        double x0y0 = 0.0625*(n01+n02+n03+n04) + 0.125*(n05+n06+n07+n08) + 0.25*(n09);
        double x1y0 = 0.0625*(n07+n12+n08+n14) + 0.125*(n09+n16+n02+n04) + 0.25*(n06);
        double x0y1 = 0.0625*(n05+n06+n23+n24) + 0.125*(n03+n04+n09+n28) + 0.25*(n08);
        double x1y1 = 0.0625*(n09+n16+n28+n34) + 0.125*(n08+n14+n06+n24) + 0.25*(n04);

        double v1 = interpolate(x0y0, x1y0, xFrac);
        double v2 = interpolate(x0y1, x1y1, xFrac);
        return interpolate(v1, v2, yFrac);
    }

    private double interpolate(double x, double y, double frac) {
        double negFrac = 1.0 - frac;
        double negFraqSqr = negFrac * negFrac;
        double fac1 = 3.0 * negFraqSqr - 2.0 * negFraqSqr * negFrac;

        double fracSqr = frac * frac;
        double fac2 = 3.0 * fracSqr - 2.0 * fracSqr * frac;

        return x * fac1 + y * fac2;
    }

    private double noise(int x, int y) {
        int n = x + y * 57;
        n = (n << 13) ^ n;
        int t = (n * (n * n * 15713 + 789221) + 1376312589) & 0x7fffffff;
        return 1.0d - (double) (t * 0.931322574615478515625e-9);
    }

}

Я пытался решить эту проблему целый день, но я не знаю, что я делаю не так. Я думал, что проблема в битовом сдвиге (private double noise(double x, double y)), но проблема не зависит от этого. Я пытался использовать этот алгоритм Перлина: https://mrl.nyu.edu/~perlin/noise/ Но эффект тот же.

1 Ответ

0 голосов
/ 11 марта 2020

Доброе утро, я, вероятно, продал проблему: D Ju sh должен спать и перезагрузить мозги)

Просто используйте максимальное значение, которое может принести целое число, и переместите генерацию координат наполовину: D

int maxint = 0x07fffffff;
double perlinNoiseHeight = floorPerlinNoise.getHeight(pX + (maxint >> 1), pY + (maxint >> 1));

Это простое решение, но оно работает) Отрицательные координаты

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...