I am trying to make a python program that can render the mandelbrot set. My full program can output an image of the set, but for some reason, it displays it cut up into opposite facing quarters.
This is the whole program.
from PIL import Image
from PIL import ImageShow
from PIL import ImageColor as ImageColour
colours = ["navy","darkblue","blue","cornflowerblue","lightsteelblue","lightskyblue","turquoise","palegreen","lawngreen","greenyellow","yellowgreen","goldenrod","gold","yellow","darkorange","orange","brown","maroon","red","deeppink","darkmagenta","magenta","mediumorchid","darkviolet","slateblue"]
def testpoint(c,zoom):
zofn = 0.0
count = 0
while str(zofn)[1] != "n" and count < (5*zoom):
#Change the formula following the "zofn =" to change the fractal formula.
zofn = (zofn*zofn)+c
count = count + 1
if str(zofn)[1] != "n":
return -1
else:
return count
def mainprogram():
zoom = int(input("Set Zoom Level. (Default: 10) ") or 10)*10
centre_x = int(input("Input centre x value. (Default: -50) ") or -50)
centre_y = int(input("Input centre y value. (Default: 0) ") or 0)
display = ""
for i in range((centre_y-250),(centre_y+250)):
for x in range((centre_x-500),(centre_x+500)):
coordinate = complex((x/zoom),(i/zoom))
value = testpoint(coordinate,zoom)
if value == -1:
colour = (0,0,0)
else:
colour = ImageColour.getrgb(colours[value % len(colours)])
result.putpixel((x,i),colour)
print("line",(i+250),"done")
ImageShow.show(result)
mainprogram()
result = Image.new("RGB",(1000,500),"Black")
mainprogram()
A screenshot of the output, obtained with default values.
It seems like each quadrant should be flipped the other way around. I've tried fiddling with the range for the for i in range((centre_y-250),(centre_y+250)) loop, with very little difference. I'm very new to programming, so I don't really know what I'm doing.
testpoint computes the color for mandelbrot centered on complex(0,0), that implies 0,0 must also correspond to the center of the image rather than the top left corner, so x and i must be moved by halt the image width and height to be a coordinate in the image.
You also want through the input values to move the drawing in the picture, so an other correction must be done on x and i removing the offset.
Here are few changes :
from PIL import Image
from PIL import ImageShow
from PIL import ImageColor as ImageColour
colours = ["navy","darkblue","blue","cornflowerblue","lightsteelblue","lightskyblue","turquoise","palegreen","lawngreen"]
def testpoint(c,zoom):
zofn = 0.0
count = 0
maxcount = 5*zoom
while zofn == zofn and count < maxcount:
#Change the formula following the "zofn =" to change the fractal formula.
zofn = (zofn*zofn) + c
count = count + 1
if zofn == zofn:
return -1
else:
return count
def mainprogram():
zoom = zoom = int(input("Set Zoom Level. (Default: 10) ") or "10")*10
centre_x = int(input("Input centre x value. (Default: -50) ") or "-50")
centre_y = int(input("Input centre y value. (Default: 0) ") or "0")
halfw = result.width // 2
halfh = result.height // 2
for i in range((centre_y - halfh),(centre_y + halfh)):
for x in range((centre_x - halfw),(centre_x + halfw)):
coordinate = complex((x/zoom),(i/zoom))
value = testpoint(coordinate,zoom)
if value == -1:
colour = (0,0,0)
else:
colour = ImageColour.getrgb(colours[value % len(colours)])
result.putpixel(((x + halfw - centre_x) % result.width,
(i + halfh - centre_y) % result.height),
colour)
print("line",(i+halfh),"done")
ImageShow.show(result)
mainprogram()
result = Image.new("RGB",(1000,500),"Black")
mainprogram()
Using the default values (just doing Enter on the questions) that produces :
Using a zoom of 10, -200 for center_x and 100 for center_y :
Notice mandelbrot is vertically symmetrical, without having to manage center_y it was trivial to compute for half the number of lines.