mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-19 18:27:29 -05:00
142 lines
4.5 KiB
Python
142 lines
4.5 KiB
Python
from array import array
|
|
|
|
from pyscript import sync, window
|
|
from perlin_py import perlin3, seed
|
|
|
|
grid_w = int(1920 * 4)
|
|
grid_h = 1080 * 2
|
|
grid_scale = 10
|
|
noise_factor = 500
|
|
grid_hs = int(grid_h/grid_scale)
|
|
grid_ws = int(grid_w/grid_scale)
|
|
crossfade_range = int(grid_ws/12.5)
|
|
height_map = array("d", [0.0] * (grid_hs * grid_ws))
|
|
edge_table = [
|
|
(), # 0
|
|
((3, 2),), # 1
|
|
((2, 1),), # 2
|
|
((3, 1),), # 3
|
|
((0, 1),), # 4
|
|
((0, 3), (1, 2)), # 5 (ambiguous)
|
|
((0, 2),), # 6
|
|
((0, 3),), # 7
|
|
((0, 3),), # 8
|
|
((0, 2),), # 9
|
|
((0, 1), (2, 3)), # 10 (ambiguous)
|
|
((0, 1),), # 11
|
|
((3, 1),), # 12
|
|
((2, 1),), # 13
|
|
((3, 2),), # 14
|
|
(), # 15
|
|
]
|
|
|
|
def update_height_map(z):
|
|
i = 0
|
|
for y in range(0, grid_h, grid_scale):
|
|
for x in range(0, grid_w, grid_scale):
|
|
# 3 octaves of noise
|
|
n = perlin3(x/noise_factor, y/noise_factor, z)
|
|
n += 0.50 * perlin3(2*x/noise_factor, 2*y/noise_factor, z)
|
|
n += 0.25 * perlin3(4*x/noise_factor, 4*y/noise_factor, z)
|
|
height_map[i] = n
|
|
i += 1
|
|
|
|
def crossfade_height_map():
|
|
for y in range(grid_hs):
|
|
for x in range(crossfade_range):
|
|
pos_i = y*grid_ws + x
|
|
neg_i = y*grid_ws + grid_ws - crossfade_range + x
|
|
weight = x/crossfade_range
|
|
old_pos = height_map[pos_i]
|
|
old_neg = height_map[neg_i]
|
|
height_map[neg_i] = height_map[pos_i] = weight * old_pos + (1.0 - weight) * old_neg
|
|
|
|
|
|
def _crossfade_height_map():
|
|
for y in range(grid_hs):
|
|
for x in range(crossfade_range):
|
|
pos_i = y*grid_ws + x
|
|
neg_i = y*grid_ws + grid_ws - x - 1
|
|
old_pos = height_map[pos_i]
|
|
old_neg = height_map[neg_i]
|
|
weight = 0.5 - x/crossfade_range/2
|
|
height_map[pos_i] = (1.0 - weight) * old_pos + weight * old_neg
|
|
height_map[neg_i] = (1.0 - weight) * old_neg + weight * old_pos
|
|
|
|
def interpolate(sq_threshold, v1, v2):
|
|
if v1 == v2:
|
|
return v1
|
|
return (sq_threshold - v1) / (v2 - v1)
|
|
|
|
stats = {'maxx': 0, 'maxy': 0, 'minx': 0, 'miny': 0}
|
|
def append_p(lines, p1, p2):
|
|
lines.append(p1[0])
|
|
lines.append(p1[1])
|
|
lines.append(0)
|
|
lines.append(p2[0])
|
|
lines.append(p2[1])
|
|
lines.append(0)
|
|
stats['maxy'] = max(p1[1], p2[1], stats['maxy'])
|
|
stats['miny'] = min(p1[1], p2[1], stats['miny'])
|
|
stats['maxx'] = max(p1[0], p2[0], stats['maxx'])
|
|
stats['minx'] = min(p1[0], p2[0], stats['minx'])
|
|
|
|
def marching_squares(height_map, sq_threshold):
|
|
lines = array("d")
|
|
|
|
for y in range(grid_hs-1):
|
|
for x in range(grid_ws-1): #cf
|
|
tl = height_map[y*grid_ws + x]
|
|
tr = height_map[y*grid_ws + x+1]
|
|
bl = height_map[(y+1)*grid_ws + x]
|
|
br = height_map[(y+1)*grid_ws + x+1]
|
|
|
|
sq_idx = 0
|
|
if tl > sq_threshold:
|
|
sq_idx |= 8
|
|
if tr > sq_threshold:
|
|
sq_idx |= 4
|
|
if br > sq_threshold:
|
|
sq_idx |= 2
|
|
if bl > sq_threshold:
|
|
sq_idx |= 1
|
|
|
|
edge_points = [
|
|
(x + interpolate(sq_threshold, tl, tr), y),
|
|
(x + 1, y + interpolate(sq_threshold, tr, br)),
|
|
(x + interpolate(sq_threshold, bl, br), y + 1),
|
|
(x, y + interpolate(sq_threshold, tl, bl)),
|
|
]
|
|
|
|
for a, b in edge_table[sq_idx]:
|
|
append_p(lines, edge_points[a], edge_points[b])
|
|
|
|
return lines
|
|
|
|
def grid_lines():
|
|
lines = array("d")
|
|
for x in range(0, grid_ws - crossfade_range, 26):
|
|
append_p(lines, (x, 0), (x, grid_hs))
|
|
for y in range(0, grid_hs, 24):
|
|
append_p(lines, (0, y), (grid_ws-crossfade_range, y))
|
|
return lines
|
|
|
|
seed(44)
|
|
sync.scale_lines(grid_ws - crossfade_range, grid_hs)
|
|
sync.print("Computing the height map")
|
|
update_height_map(0)
|
|
sync.print("Cross-fading the height map")
|
|
crossfade_height_map()
|
|
sync.draw_lines(grid_lines(), 'grid')
|
|
sync.draw_lines(marching_squares(height_map, 0), 'zero')
|
|
sync.draw_lines(marching_squares(height_map, 0.3), 'positive')
|
|
sync.draw_lines(marching_squares(height_map, -0.3), 'negative')
|
|
sync.draw_lines(marching_squares(height_map, 0.45), 'positive')
|
|
sync.draw_lines(marching_squares(height_map, -0.45), 'negative')
|
|
sync.draw_lines(marching_squares(height_map, 0.6), 'positive')
|
|
sync.draw_lines(marching_squares(height_map, -0.6), 'negative')
|
|
sync.draw_lines(marching_squares(height_map, -0.8), 'negative')
|
|
sync.draw_lines(marching_squares(height_map, 0.8), 'positive')
|
|
print(stats)
|
|
sync.drawing_done()
|