2013-03-21 4 views
0

У меня есть суровое количество карт шума perlin и вес для каждого. Сумма всех весов равна 1, но это не имеет значения.Map Generator с взвешенными шумами Perlin

Я хочу получить этот шум с наивысшей оценкой веса.

Мой первый подход состоял в том, чтобы получить числа от каждого шума perlin, преобразовать их в проценты (у меня есть таблица петли), умножить на вес и выбрать самое высокое значение. Но этот подход имеет огромный недостаток: он различает меньшие веса и предпочитает более крупные, и поэтому беспорядок распространяет. Я хочу, чтобы вес 0,2 появился в 20%.

Я хочу использовать это для генератора карт, чтобы выбрать тип плитки. Я использую множественные шумы perlin, потому что я хочу использовать множество разных типов плитки, чтобы граничить друг с другом и, следовательно, не может использовать градиент.

Кто-нибудь знает, как исправить этот недостаток или по-другому создать таблицы на основе плитки?

EDIT: Тем временем я понял, почти приемлемое решение:

final float[] values = new float[noises.length]; 
for (int i = 0; i < values.length; i++) 
    values[i] = noises[i].get(x, y) * (1f + (weights[i] - 1f/noises.length)); 

int max = 0; 
for (int i = 1; i < values.length; i++) 
    if (values[i] > values[max]) 
     max = i; 
return noises[max]; 

Это только изъян быть неточными. Даже при весе 0f шум будет сохраняться примерно в 6% случаев.

+0

Что именно вы подразумеваете под «наивысшей оценкой веса»? Когда я впервые прочитал, я предположил, что вы * хотели * различать малые шумовые карты. –

+0

Что-то вроде perlin value * weight, а затем выберите самый большой. Но я также хочу, чтобы каждый из них был выбран равным весу, например, шум с весом 0,2 должен быть самым высоким в 20% случаев. – DiddiZ

ответ

1

Возможно, решение было бы что-то вроде этого:.

Perlin pickOne(Perlin[] noise, double[] weights) { 
    double sum = 0; 
    for(double weight : weights) sum += weight; 
    double choice = Math.random() * sum; 
    for(int i = 0; i < weights.length; ++i) { 
     choice -= weights[i]; 
     if(choice <= 0) { 
     return noise[i]; 
     } 
    } 
    throw new IllegalArgumentException("Must have at least one weight!"); 
} 

(То есть, выбрать один из шума карты полностью основано на весах, а не значение карты Что я делаю, чтобы выбрать здесь можно представить себе, как выкладывать все весы от конца до конца на числовой линии, выбирая значение внутри них, а затем выясняя, какой вес он попадает внутрь.)

+0

Hm, так как это игнорирует значения карты, результирующая карта выглядит очень случайной и разбросанной. – DiddiZ

0

«Мой первый подход заключался в том, чтобы получить числа от каждого шума perlin, преобразуйте их в проценты (у меня есть таблица циклов для этого), умножьте их на вес и выберите самое высокое значение. oach имеет огромный недостаток: он различает меньшие веса и предпочитает более крупные и таким образом помешает распространению. Я хочу, чтобы вес 0,2 появляться в 20% «

То, что я хотел бы предложить:.

1) Сложите сумму всех процентных * веса

2) Выбрать случайное число в диапазоне от 0 и просуммировать

3) Перечислите добавление процента * элементов веса, пока не превысить случайное число - выбрать, что

Это сделает случайное распределение по всем возможностям, которые взвешиваются по их процентному * весу, так что если у вас есть 2, 8 и 6 появляется 2/16 времени, 8 8/16 времени и 6 6/16 времени.

Смежные вопросы