如何绘制 Buddhabrot 分形?

How to draw Buddhabrot fractal?

我正在尝试在 Python 中实现 Buddhabrot 分形。我阅读了很多文章和帖子,但我认为我误解了一些东西(只看图片)。有人可以写个伪代码吗?

我的代码是这样的:

from multiprocessing import Pool
from random import randrange
import matplotlib.pyplot as plt
import numpy as np
from math import ceil


maxiter       = 1000
points        = 1000
xmin, xmax    = -2, 1
ymin, ymax    = -2, 1
cores         = 4
width, height = 200, 200


maxn         = width * height
incrx, incry = abs(xmax - xmin) / width, abs(ymax - ymin) / height

def randomComplexGenerator():
  for i in range(points):
    n = randrange(maxn)
    yield complex(n // height * incrx, n % width * incry)

def buddhabrot(c):
  m, z, i = np.zeros((width, height)), c, 0
  while i < maxiter and abs(z) < 2:
    x, y     = ceil(z.real / incrx), ceil(z.imag / incry)
    m[x, y] += 1
    z        = z ** 2 + c
    i       += 1
  return m if i == maxiter else 0

if __name__ == '__main__':
  a = np.linspace(xmin, xmax, width)
  b = np.linspace(ymin, ymax, height)
  with Pool(cores) as p:
    ms = p.map(buddhabrot, (c for c in randomComplexGenerator()))
  res = 0
  for m in ms:
    res += m
  plt.axis('off')
  plt.imshow(res)
  plt.show()

用我的代码生成的图像是这样的(lel):

几天后,这是我创建的代码,它似乎适当地生成了分形。欢迎任何性能建议。

from multiprocessing import Pool
from random import randrange
import matplotlib.pyplot as plt
import numpy as np


cores         = 4
maxiter       = 10000
points        = 1000000
width, height = 200, 200
rdom, idom    = (-2, 2), (-2, 2)

xdom, ydom    = (0, width - 1), (0, height - 1)

def randomComplex():
  r = np.interp(randrange(xdom[0], xdom[1]), xdom, rdom)
  i = np.interp(randrange(ydom[0], ydom[1]), ydom, idom)
  return (r, i)

def complex2pixel(c):
  x = int(np.interp(c[0], rdom, xdom))
  y = int(np.interp(c[1], idom, ydom))
  return (x, y)

def escapedPixels(c):
  pixels, z = {}, c
  for i in range(maxiter):
    z2 = (z[0] * z[0], z[1] * z[1]) 
    if z2[0] + z2[1] > 4: break
    p = complex2pixel(z)
    try: pixels[p] += 1
    except: pixels[p] = 1
    z = (z2[0] - z2[1] + c[0], 2 * z[0] * z[1] + c[1])
  return pixels if i < maxiter - 1 else {}

if __name__ == '__main__':
  with Pool(cores) as p:
    ds = p.map(escapedPixels, (randomComplex() for i in range(points)))
  m = np.zeros((width, height))
  for d in ds:
    for p in d:
      m[p] += d[p]
  plt.axis('off')
  plt.imshow(m)
  plt.show()