Странный трехмерный результат процедурной генерации

Итак, в течение последних нескольких дней я работал над созданием программы процедурной генерации, написанной на java, однако всякий раз, когда я делаю вывод, он выходит с вымытой, похожей на бумагу текстурой. Я не понимаю, почему он это делает, и, хотя это довольно круто, мне было интересно, может ли кто-нибудь объяснить мне, как моя программа достигает такого результата.

Источник: http://pastebin.com/frCh03VW

Я ожидал, что эта логика создаст облако, похожее на карту высот, но вместо этого она дала мне следующее:

Большое изображение: http://i.imgur.com/8MXRBNk.jpg


person Nicholas Hollander    schedule 27.09.2013    source источник


Ответы (2)


Николай,

Заранее прошу прощения, если это неверно, но, просмотрев ваш код и скомпилировав его самостоятельно, я обнаружил, что шаблон во многом зависит от переменной mshift. Если вы установите для него относительно большое число (для моих целей я установил его на 1000), вы обнаружите намного больше статического и белого шума. И наоборот, если вы установите его относительно низким (для моих целей я установил его на 10), вы получите описание, похожее на океанскую волну или вымытое бумажное описание.

Я бы предположил, без длительного тестирования, что созданное изображение во многом связано с тем фактом, что вы просматриваете каждое значение x перед соответствующим y.

У меня не так много времени, чтобы участвовать в этом, так как у меня есть мой собственный проект, который должен быть запланирован сегодня в 23:59, но, возможно, проект, который я сделал некоторое время назад, может вам помочь. Я приготовила пасту на случай, если вы нашли в ней пользу:

http://pastebin.com/c0umWA1N

person Fiki    schedule 27.09.2013

Вы используете java.util.Random для создания текстуры. Конечно, в компьютерах нет ничего случайного. Стандартная библиотека Java использует классический линейный генератор конгруэнтных псевдослучайных чисел, который является быстрым и удобным для большинства целей. , но по-прежнему считается слабым местом для серьезных вещей. Под «слабым» я подразумеваю, что он может быть предсказуемым и проявляет «неслучайность» при интенсивном использовании. Возможно, это источник паттернов, которые вы здесь видите.

Другой возможный источник проблемы заключается в том, что вы сначала создаете массив случайных начальных чисел. Но если вы посмотрите на реализацию Random.next() в java.util:

protected int next(int bits) {
    long oldseed, nextseed;
    AtomicLong seed = this.seed;
    do {
        oldseed = seed.get();
        nextseed = (oldseed * multiplier + addend) & mask;
    } while (!seed.compareAndSet(oldseed, nextseed));
    return (int)(nextseed >>> (48 - bits));
}

вы видите, что процесс Random состоит в том, чтобы сгенерировать новое семя и вернуть значение на основе простого вычисления этого семени. У меня нет математических знаний, чтобы быть уверенным в этом, но, возможно, этот метод позволит создать список начальных чисел, которые будут давать похожие псевдослучайные последовательности, когда вы будете их использовать впоследствии, потому что они каким-то образом зависят друг от друга, поскольку были генерируется тем же генератором случайных чисел, а также генерирует шаблоны.

Что вы можете попробовать: используйте лучший псевдослучайный генератор. Вы можете использовать java.security.SecureRandom, который является «криптографически стойким», поэтому его должно быть достаточно для вашего использования. К сожалению, это не так быстро, как java.util.Random. Но вы можете хотя бы попробовать и посмотреть, найдете ли вы те же шаблоны. Если нет, значит, случайный генератор был плохим; если вы все еще находите закономерности, то, скорее всего, это исходит от вашего алгоритма.

Если я прав, говоря, что псевдослучайный генератор недостаточно случайный, и если SecureRandom слишком медленный для вас, вы можете найти в Интернете реализацию алгоритма «Мерсенн Твистер», который быстрее и лучше, чем метод линейной конгруэнтности .

person Cyrille Ka    schedule 27.09.2013
comment
Я попытался заменить свои Random на Secure-random, но это не имело никакого значения. Что странно, потому что я действительно думал, что это сработает. В любом случае спасибо, :) - person Nicholas Hollander; 28.09.2013