Перлин Шум в Java - PullRequest
       19

Перлин Шум в Java

8 голосов
/ 03 апреля 2011

Для проекта клеточных автоматов, над которым я работаю, мне нужно генерировать двумерные логические массивы случайным образом, используя разные алгоритмы и методы.На данный момент у меня есть только один тип рандомизации в приложении - цикл по каждой ячейке в массиве и генерация случайной двойной переменной, а затем, если случайное число больше 0,5, тогда я устанавливаю эту ячейку в true, если не устанавливаетсяв false.

Я хотел бы взглянуть на генерацию этих логических матриц, используя более интересные алгоритмы, такие как Perlin Noise или что-то в этом роде.Генераторы шума, которые используются при создании ландшафта или что-то в этом роде, могут быть хорошими, если вы знаете что-либо кроме Perlin Noise (мировое поколение Minecraft дало мне эту идею).

Единственная проблема в том, что я понятия не имею, гденачало (есть идеи?):)

Ответы [ 2 ]

9 голосов
/ 04 апреля 2011

Первое, о чем я подумал, это фрактал со случайным смещением.Он также используется для создания ландшафта и проще, чем Perlin Noise.

package so;

import java.util.Random;

public class Noise {
    /** Source of entropy */
    private Random rand_;

    /** Amount of roughness */
    float roughness_;

    /** Plasma fractal grid */
    private float[][] grid_;


    /** Generate a noise source based upon the midpoint displacement fractal.
     * 
     * @param rand The random number generator
     * @param roughness a roughness parameter
     * @param width the width of the grid
     * @param height the height of the grid
     */
    public Noise(Random rand, float roughness, int width, int height) {
        roughness_ = roughness / width;
        grid_ = new float[width][height];
        rand_ = (rand == null) ? new Random() : rand;
    }


    public void initialise() {
        int xh = grid_.length - 1;
        int yh = grid_[0].length - 1;

        // set the corner points
        grid_[0][0] = rand_.nextFloat() - 0.5f;
        grid_[0][yh] = rand_.nextFloat() - 0.5f;
        grid_[xh][0] = rand_.nextFloat() - 0.5f;
        grid_[xh][yh] = rand_.nextFloat() - 0.5f;

        // generate the fractal
        generate(0, 0, xh, yh);
    }


    // Add a suitable amount of random displacement to a point
    private float roughen(float v, int l, int h) {
        return v + roughness_ * (float) (rand_.nextGaussian() * (h - l));
    }


    // generate the fractal
    private void generate(int xl, int yl, int xh, int yh) {
        int xm = (xl + xh) / 2;
        int ym = (yl + yh) / 2;
        if ((xl == xm) && (yl == ym)) return;

        grid_[xm][yl] = 0.5f * (grid_[xl][yl] + grid_[xh][yl]);
        grid_[xm][yh] = 0.5f * (grid_[xl][yh] + grid_[xh][yh]);
        grid_[xl][ym] = 0.5f * (grid_[xl][yl] + grid_[xl][yh]);
        grid_[xh][ym] = 0.5f * (grid_[xh][yl] + grid_[xh][yh]);

        float v = roughen(0.5f * (grid_[xm][yl] + grid_[xm][yh]), xl + yl, yh
                + xh);
        grid_[xm][ym] = v;
        grid_[xm][yl] = roughen(grid_[xm][yl], xl, xh);
        grid_[xm][yh] = roughen(grid_[xm][yh], xl, xh);
        grid_[xl][ym] = roughen(grid_[xl][ym], yl, yh);
        grid_[xh][ym] = roughen(grid_[xh][ym], yl, yh);

        generate(xl, yl, xm, ym);
        generate(xm, yl, xh, ym);
        generate(xl, ym, xm, yh);
        generate(xm, ym, xh, yh);
    }


    /**
     * Dump out as a CSV
     */
    public void printAsCSV() {
        for(int i = 0;i < grid_.length;i++) {
            for(int j = 0;j < grid_[0].length;j++) {
                System.out.print(grid_[i][j]);
                System.out.print(",");
            }
            System.out.println();
        }
    }


    /**
     * Convert to a Boolean array
     * @return the boolean array
     */
    public boolean[][] toBooleans() {
        int w = grid_.length;
        int h = grid_[0].length;
        boolean[][] ret = new boolean[w][h];
        for(int i = 0;i < w;i++) {
            for(int j = 0;j < h;j++) {
                ret[i][j] = grid_[i][j] < 0;
            }
        }
        return ret;
    }


    /** For testing */
    public static void main(String[] args) {
        Noise n = new Noise(null, 1.0f, 250, 250);
        n.initialise();
        n.printAsCSV();
    }
}

random displacement fractal plot 1 random displacement fractal plot 2 random displacement fractal plot 3

4 голосов
/ 05 апреля 2011

У меня есть некоторые реализации перлин-шума и некоторые другие функции генерации шума в коде моей библиотеки:

http://code.google.com/p/mikeralib/source/browse/#svn%2Ftrunk%2FMikera%2Fsrc%2Fmain%2Fjava%2Fmikera%2Fmath

Не стесняйтесь исследовать / использовать (код GPL с открытым исходным кодом, на основе кода J3D).

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