Created
August 9, 2015 17:03
-
-
Save osamaar/e79bfbcf9528936fbba5 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