-
-
Save antiface/27d669021366511fe687a2d6b80bfe1d to your computer and use it in GitHub Desktop.
Value Noise implementation in python 2.7.x
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from random import random, seed | |
def debug_func(fn): | |
def new(*args, **kwargs): | |
print 'DEBUG: function call:', fn.func_name, args, kwargs | |
return fn(*args, **kwargs) | |
return new | |
#@debug_func | |
def octave(step, amp, bitmap, modifier): | |
size = len(bitmap) | |
shift = step - 1 | |
for i in xrange(0, size, step): | |
for j in xrange(0, size, step): | |
modifier[i ][j ] = random()%amp - 0.5*amp | |
modifier[i ][j+shift] = random()%amp - 0.5*amp | |
modifier[i+shift][j ] = random()%amp - 0.5*amp | |
modifier[i+shift][j+shift] = random()%amp - 0.5*amp | |
for i in xrange(0, size, step): | |
for j in xrange(0, size, step): | |
a = max(i-1, 0) | |
b = max(j-1, 0) | |
r = min(step+1, size) | |
bilinear(modifier, a, b, r) | |
for i in xrange(size): | |
for j in xrange(size): | |
bitmap[i][j] += modifier[i][j] | |
def print_map(bitmap): | |
print '\n'.join([str([round(y, 2) for y in x]) for x in bitmap]) | |
def bilinear(bitmap, i0, j0, size): | |
# bilinear interpolation by interpolating on x axis then y axis | |
# en.wikipedia.org/wiki/Bilinear_interpolation#Algorithm | |
shift = size - 1 | |
denum = shift*shift | |
for i in xrange(i0, i0+size): | |
for j in xrange(j0, j0+size): | |
enum = bitmap[i0 ][j0 ] * (i0 + shift - i) * (j0 + shift - j) + \ | |
bitmap[i0+shift][j0 ] * (i - i0 ) * (j0 + shift - j) + \ | |
bitmap[i0 ][j0+shift] * (i0 + shift - i) * (j - j0 ) + \ | |
bitmap[i0+shift][j0+shift] * (i - i0 ) * (j - j0 ) | |
bitmap[i][j] = enum/float(denum) | |
def test_bilinear(): | |
m = [[0, 0, 0, 3],[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 3]] | |
print m | |
bilinear(m, 0, 0, 4) | |
print m | |
@debug_func | |
def generate(size, octaves, map_seed=None): | |
if 2**octaves > size: | |
raise ValueError('Cannot have more octaves than map size') | |
seed(map_seed) | |
bitmap = [[0]*size for i in xrange(size)] | |
modifier = [[0]*size for i in xrange(size)] | |
# step controls level of detail | |
step = size | |
amp = 1 | |
presist = .5 | |
while step > 1 and octaves !=0: | |
octave(step, amp, bitmap, modifier) | |
step /= 2 | |
amp *= presist | |
print octaves | |
octaves -= 1 | |
return bitmap | |
def normalize(bitmap, start, end): | |
size = len(bitmap) | |
peak = 1.0 * max(max(x) for x in bitmap) | |
valley = 1.0 * min(min(x) for x in bitmap) | |
scale = end - start | |
for i in xrange(size): | |
for j in xrange(size): | |
bitmap[i][j] = start + scale*(bitmap[i][j] - valley)/(peak - valley) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment