1
from PIL import Image
import numpy as np
import math

class Fractal(object):

    def __init__(self, resolution=(720,720), x_range=(-2.0,2.0), y_range=(-2.0,2.0), maxIterations=255, zoom=0, zoomRate=0):
        self.resolution = resolution
        self.x_range = x_range
        self.y_range = y_range
        self.maxIterations = maxIterations
        self.zoom = zoom
        self.zoomRate = zoomRate

    def computePixel(self, x, y):
        z = complex(0.0,0.0)
        c = complex(x,y)
        iterations = 0
        while iterations < self.maxIterations or abs(z)<2:
            z = z*z + c
            iterations += 1
        # pixelHue = (360/self.maxIterations)*iterations
        # RGB = hsv_to_rgb(pixelHue, 0.0, 0.0)
        # return RGB
        return iterations

    def generateFrame(self):
        #x_max, x_min, y_max, y_min = self.zoom()
        x_max, x_min, y_max, y_min = (self.x_range[1],self.x_range[0],self.y_range[1],self.y_range[0])
        x_increment = (x_max - x_min)/self.resolution[0]
        print(x_increment)
        y_increment = (y_max - y_min)/self.resolution[1]
        print(y_increment)
        frame = []
        yPixels = []
        for x in np.arange(x_min, x_max, x_increment):
            for y in np.arange(y_min, y_max, y_increment):
                x,y = float(x), float(y)
                iterations = self.computePixel(x,y)
                print(x,y,iterations)
        #         pixel_RGB= self.computePixel(x,y)
        #         yPixels.append(pixel_RGB)
        #     frame.append(yPixels)
        # return frame


    def zoom(self):
        '''this is the change that will happen in one second'''
        x_max = self.x_range[1]-(self.zoomRate/2)
        x_min = self.x_range[0]+(self.zoomRate/2)
        y_max = self.y_range[1]-(self.zoomRate/2)
        y_min = self.y_range[0]+(self.zoomRate/2)
        return (x_max, x_min, y_max, y_min)

    def sweep(self):
        for x in np.arange(self.size[0]):
            for y in np.arange(self.size[1]):
                pass



def hsv_to_rgb(h, s, v):
    if s == 0.0: return (v, v, v)
    i = int(h*6.) # XXX assume int() truncates!
    f = (h*6.)-i; p,q,t = v*(1.-s), v*(1.-s*f), v*(1.-s*(1.-f)); i%=6
    if i == 0: return (v, t, p)
    if i == 1: return (q, v, p)
    if i == 2: return (p, v, t)
    if i == 3: return (p, q, v)
    if i == 4: return (t, p, v)
    if i == 5: return (v, p, q)

f = Fractal()
f.generateFrame()     

Currently, I'm only trying to display the first frame of the GIF, i.e. the non-zoomed-into Mandelbrot set. However, when I try to iterate through all the pixel values the iteration stops at x=-1.8611111111111116 and y=-0.005555555555562641

I'm guessing this is because of some overflow error occurring when y is supposed to be zero, but I don't know how to solve this.

Here's a final screenshot of the command line where I'm printing the real and imaginary parts of all complex numbers with the number of iterations it took for that number to converge (or not if the output is 255).

enter image description here

Spektre
  • 49,595
  • 11
  • 110
  • 380
  • What do you mean by "the iteration stops" - do you get an error? does it go into an infinite loop? Does the process silently exit? – Tom Dalton Apr 21 '20 at 16:12
  • @Katsu Yeah, but shouldn't it exit the while loop because of the iterations < self.maxIterations condition? –  Apr 21 '20 at 16:25
  • @TomDalton I don't get any error messages and it doesn't exit the process either. I have to keyboard interrupt to to stop it because it's just stuck there. This makes me think it's still running the computation in the background but I'm not able to figure out if it's an infinite loop. –  Apr 21 '20 at 16:28
  • It's not totally clear which loop we're talking about. Can you add debug logging inside the loop to log out the loop variables and prove to yourself if it's spinning inside the loop or of it's hung/staled somewhere else? – Tom Dalton Apr 21 '20 at 16:46
  • 3
    You want `and` in your `while` loop condition: `while iterations < self.maxIterations and abs(z)<2:` instead of `while iterations < self.maxIterations or abs(z)<2:`. Otherwise, the loop will never exit if the iteration stays bounded. – Mark Dickinson Apr 21 '20 at 17:04
  • @Mark Yes, you're right. For some reason I thought I had read an implementation which used `or` instead of `and` which is why I subconsciously did it without thinking it through. Thanks! –  Apr 21 '20 at 17:14
  • these related QAs might be interesting for you: [Can't find a way to color the Mandelbrot-set the way i'm aiming for](https://stackoverflow.com/a/56197067/2521214) and [How to adjust panning while zooming](https://stackoverflow.com/a/56327701/2521214) and [How to express tetration function, for complex numbers](https://stackoverflow.com/a/56735614/2521214) – Spektre Apr 22 '20 at 07:52

1 Answers1

0

You need to change your while loop condition to:

while iterations < self.maxIterations and abs(z)<2:

Otherwise, the loop is running for a long time since abs(z) is less than 2.

Ehsan
  • 12,072
  • 2
  • 20
  • 33