2013-10-08 2 views
1

Я хочу играть с процедурными алгоритмов генерации контента, и решил начать с шумами (Перлин, значение и т.д.)Реализация функции шума в Python из кода C

Для этого я хочу иметь общий п-мерное шум функция. Для этого я написал функцию, которая возвращает функцию генерации шума данного измерения:

small_primes = [1, 83, 97, 233, 61, 127] 

def get_noise_function(dimension, random_seed=None): 
    primes_list = list(small_primes) 
    if dimension > len(primes_list): 
     primes_list = primes_list * (dimension/len(primes_list)) 
    rand = random.Random() 
    if random_seed: 
     rand.seed(random_seed) 
    # random.shuffle(primes_list) 
    rand.shuffle(primes_list) 

    def noise_func(*args): 
     if len(args) < dimension: 
      # throw something 
      return None 
     n = [a*b for a, b in zip(args, primes_list)] 
     n = sum(n) 
     #n = (n << 13) ** n 
     n = (n << 13)^n 
     nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff 
     return 1.0 - (nn/1073741824.0) 

    return noise_func 

, проблема, я считаю, с расчетами. Я на основе моего кода на этих двух статей:

Пример одного из моих тестов:

f1 = get_noise_function(1, 10) 
print f1(1) 
print f1(2) 
print f1(3) 
print f1(1) 

Он всегда возвращается - 0.281790983863, даже при более высоких размерах и разных семенах.

Проблема, я считаю, заключается в том, что в C/C++ происходит переполнение некоторых вычислений, и все работает. В python он просто вычисляет гигантское число.

Как я могу исправить это или, если возможно, как я могу сгенерировать псевдослучайную функцию, которая после посева для определенного ввода всегда возвращает одно и то же значение.

[EDIT] Исправлен код. Теперь это работает.

ответ

1

Если ссылочный код от Hugo Элиас:

x = (x<<13)^x 

у вас есть:

n = (n << 13) ** n 

Я считаю, что Элиас делает побитового XOR, в то время как вы эффективно повысить 8192 * п к мощность из n. Это дает вам огромное значение. Тогда

nn = (n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff 

принимает, что гигантский п и делает его еще больше, пока, наконец, не выбрасывайте все, кроме последних 31 бит. Это не имеет большого смысла ;-)

Попробуйте изменить свой код:

n = (n << 13)^n 

и посмотреть, поможет ли это.

+0

Да, это было. Прочитав столько математики, я подумал, что это было возвеличивание. Я исправил еще одну ошибку (опечатку), и теперь она работает. Кроме того, святое дерьмо! На меня ответил Тим Петерс! –