1
我正在研究一种Python脚本,它可以在通常的顺序中产生(包裹)菱形方形分形:而不是从外角和细分为更小的正方形,它从任意点开始递归地向外运行,只生成最终值依赖的点。下面是我写的,以确定如何处理每个点的功能:菱形方形分形的“内外”实现问题
def stepinfo(x, y):
y1 = y-(y&(y-1))
x1 = x-(x&(x-1))
sum = x1 + y1
return [((sum&(sum-1)) == 0), min(y1, x1)]
返回的第一个值是一个布尔值,指定是否该点应被菱形或方形步骤中产生;第二个值指定步骤的网格大小。它很好用,除非x或y为零 - 那么返回的步长为零,脚本循环。但是,如果我将分形平铺到2x2网格中,并通过单击瓦片的右下角副本(即,远离窗口的零轴)来指定点,则整个分形将完美生成。但我似乎无法通过向鼠标坐标添加多个贴图大小或沿着这些行的任何内容来“伪造”此结果。
有什么建议吗?
下面是完整的脚本(我已经停止递归避免无端环,如果x或y = 0,但它仍然缺少点产生伪影):
MAPEXPONENT = 8
import pygame
import random
MAPSIZE = 2**int(MAPEXPONENT)
MAP = [[[None] for col in range(MAPSIZE)] for row in range(MAPSIZE)]
def point(x, y):
return MAP[x%MAPSIZE][y%MAPSIZE]
def displace(value, scale):
displaced = (value + (random.random()-.5) * scale * 12)
if displaced > 1 or displaced < 0: displaced = 1-displaced%1
return displaced
def average(values):
realvalues = []
for value in values:
if value <> None: realvalues.append(value)
if realvalues: return float(sum(realvalues, 0))/len(realvalues)
else: return 0
def color_point(x, y, array):
pixel = point(x, y)[0]
green = pixel*255
red = pixel**.5*255
blue = 255-green
array[x%MAPSIZE][y%MAPSIZE] = [min(255, max(0, int(red))),
min(255, max(0, int(green))),
min(255, max(0, int(blue)))]
def stepinfo(x, y):
y1 = y-(y&(y-1))
x1 = x-(x&(x-1))
sum = x1 + y1
return [((sum&(sum-1)) == 0), min(y1, x1)]
def makepoint(x, y, map_array):
midpoint = point(x, y)
if midpoint[0] == None:
step = stepinfo(x, y)
size = step[1]
scale = float(size)/MAPSIZE
heights = []
if step[0]: points = [[x-size, y-size], [x+size, y-size],
[x-size, y+size], [x+size, y+size]]
else: points = [[x, y-size], [x, y+size],
[x-size, y], [x+size, y]]
for p in points:
if point(p[0], p[1])[0] == None and p[0] and p[1]:
makepoint(p[0], p[1], map_array)
heights.append(point(p[0], p[1])[0])
midpoint[0] = displace(average(heights), scale)
color_point(x, y, map_array)
return midpoint
pygame.init()
screen = pygame.display.set_mode((2*MAPSIZE, 2*MAPSIZE))
map_surface = pygame.surface.Surface((MAPSIZE, MAPSIZE))
brush = 4+MAPSIZE/32
map_surface_array = pygame.surfarray.pixels3d(map_surface)
MAP[0][0][0] = random.random()
color_point(0, 0, map_surface_array)
del map_surface_array
running = True
while running:
event = pygame.event.wait()
if event.type == pygame.MOUSEBUTTONDOWN:
while event.type <> pygame.MOUSEBUTTONUP:
event = pygame.event.wait()
x0, y0 = pygame.mouse.get_pos()
map_surface_array = pygame.surfarray.pixels3d(map_surface)
for x in range(x0-brush, x0+brush):
for y in range(y0-brush, y0+brush):
if (x-x0)**2+(y-y0)**2 < brush**2:
makepoint(x, y, map_surface_array)
del map_surface_array
for x, y in [(0,0), (MAPSIZE,0), (0,MAPSIZE), (MAPSIZE,MAPSIZE)]:
screen.blit(map_surface, (x, y))
pygame.display.update()
elif event.type == pygame.QUIT:
running = False
pygame.quit()