2017-06-29 2 views
2

Est-il possible de changer la formule de l'ensemble de mandelbrot (qui est f (z) = z^2 + c par défaut) à un autre (f (z) = z^2 + c * e^(- z) est ce que j'ai besoin) lors de l'utilisation de l'algorithme de temps de fuite et si possible comment? J'utilise actuellement ce code par FB36jeu de mandelbrot multithread

# Multi-threaded Mandelbrot Fractal (Do not run using IDLE!) 
# FB - 201104306 
import threading 
from PIL import Image 
w = 512 # image width 
h = 512 # image height 
image = Image.new("RGB", (w, h)) 
wh = w * h 
maxIt = 256 # max number of iterations allowed 
# drawing region (xa < xb & ya < yb) 
xa = -2.0 
xb = 1.0 
ya = -1.5 
yb = 1.5 
xd = xb - xa 
yd = yb - ya 
numThr = 5 # number of threads to run 
# lock = threading.Lock() 

class ManFrThread(threading.Thread): 
    def __init__ (self, k): 
      self.k = k 
      threading.Thread.__init__(self) 
    def run(self): 
     # each thread only calculates its own share of pixels 
     for i in range(k, wh, numThr): 
      kx = i % w 
      ky = int(i/w) 
      a = xa + xd * kx/(w - 1.0) 
      b = ya + yd * ky/(h - 1.0) 
      x = a 
      y = b 
      for kc in range(maxIt): 
       x0 = x * x - y * y + a 
       y = 2.0 * x * y + b 
       x = x0     
       if x * x + y * y > 4: 
        # various color palettes can be created here 
        red = (kc % 8) * 32 
        green = (16 - kc % 16) * 16 
        blue = (kc % 16) * 16 
        # lock.acquire() 
        global image 
        image.putpixel((kx, ky), (red, green, blue)) 
        # lock.release() 
        break 

if __name__ == "__main__": 
    tArr = [] 
    for k in range(numThr): # create all threads 
     tArr.append(ManFrThread(k)) 
    for k in range(numThr): # start all threads 
     tArr[k].start() 
    for k in range(numThr): # wait until all threads finished 
     tArr[k].join() 
    image.save("MandelbrotFractal.png", "PNG") 
+1

C'est certainement possible, même si les formules deviennent beaucoup plus complexes. ('x0 = x * x - y * y + exp (-x) * (a * cos (y) + b * sin (y))' et 'y = 2.0 * x * y + exp (-x) * (b * cos (y) - a * sin (y)) ' Du haut de ma tête, je ne peux pas répondre si l'heuristique d'échappement (| z | ²> 4) fonctionne toujours ici, mais ça pourrait être –

+0

Donc, c'est la fractale que j'ai eu en utilisant vos formules si vous vous demandiez https://www.dropbox.com/s/qtbh7bobrt9nhql/fractal.PNG?dl=0 – Leizer

Répondre

0

À partir du code, je déduis que z = x + y * i et c = a + b * i. Cela correspond à f(z) - z ^2 + c. Vous voulez f(z) = z ^2 + c * e^(-z). Rappelez-vous que e^(-z) = e^-(x + yi) = e^(-x) * e^i(-y) = e^(-x)(cos(y) - i*sin(y)) = e^(-x)cos(y) - i (e^(-x)sin(y)). Ainsi, vous devez mettre à jour vos lignes être les suivantes:

x0 = x * x - y * y + a * exp(-x) * cos(y) + b * exp(-x) * sin(y); 
y = 2.0 * x * y + a * exp(-x) * sin(y) - b * exp(-x) * cos(y) 
x = x0 

Vous devrez peut-être ajuster maxIt si vous ne recevez pas le niveau de différenciation des fonctionnalités que vous êtes après (il pourrait prendre des itérations plus ou moins pour échapper maintenant , en moyenne) mais cela devrait être l'expression mathématique que vous recherchez. Comme indiqué dans les commentaires, vous devrez peut-être ajuster le critère lui-même et pas seulement les itérations maximales afin d'obtenir le niveau de différenciation souhaité: changer le maximum n'aide pas pour ceux qui ne s'échappent jamais.

Vous pouvez essayer de trouver une bonne condition d'évacuation ou simplement essayer certaines choses et voir ce que vous obtenez.

+1

Il faut être prudent avec le critère d'échappement, puisque 'c * exp (-z)' pourrait être beaucoup plus petit (ou plus grand) que 'c', puisqu'il dépend de la valeur absolue et de l'argument du nombre complexe' z'. essayer de trouver une preuve standard peut être ajustée à cette nouvelle formule, mais je ne suis pas tout à fait sûr: –

+0

'e^i (-y) = cos (y) - i * sin (y)', le sinus est une fonction étrange.Voir aussi le commentaire de Tobias sous la question. – LutzL