Extra¶
Mandelbrot¶
Tijdens deze opdracht ga je een programma schrijven om de punten in en rond de mandelbrotverzameling weer te geven en te verkennen.
De vier rekenfuncties hieronder staan in cellen die bij de build worden uitgevoerd, met hun assertions eronder. De functies die een PNG-bestand tekenen staan daaronder als codeblok: die hebben de module png uit mandelbrot.zip nodig en schrijven een bestand weg, dus ze horen thuis op je eigen machine en niet in de build.
De functie mult¶
def mult(c, n):
"""Vermenigvuldigt c met de positieve integer n, met alleen een lus en optellen."""
result = 0
for i in range(n):
result += c
return result
assert mult(3, 5) == 15
assert mult(6, 7) == 42
assert mult(1.5, 28) == 42.0
De functie update¶
def update(c, n):
"""Begint met z = 0, voert z = z**2 + c n keer uit en geeft de laatste z terug."""
z = 0
for i in range(n):
z = z**2 + c
return z
assert update(1, 3) == 5
assert update(-1, 3) == -1
assert update(-1, 10) == 0
De functie in_mset¶
def in_mset(c, n):
"""Bepaalt of c binnen de mandelbrotverzameling lijkt te vallen.
c is de waarde uit de stap z = z**2 + c, en n het aantal keren dat
die stap hoogstens wordt uitgevoerd.
Geeft False terug zodra abs(z) groter wordt dan 2, en True als dat
binnen n stappen niet gebeurt.
"""
z = 0
for i in range(n):
z = z**2 + c
if abs(z) > 2:
return False
return True
c = 0 + 0j
assert in_mset(c, 25) == True
c = 3 + 4j
assert in_mset(c, 25) == False
c = 0.3 + -0.5j
assert in_mset(c, 25) == True
c = -0.7 + 0.3j
assert in_mset(c, 25) == False
c = 0.42 + 0.2j
assert in_mset(c, 25) == True
assert in_mset(c, 50) == False
De functie scale¶
def scale(pix, pix_max, float_min, float_max):
"""Geeft de floating-pointwaarde terug die bij pixel pix hoort.
pix is de huidige pixelkolom (of pixelrij), pix_max het totale aantal
pixelkolommen, en float_min en float_max zijn de onder- en bovengrens
van het bereik.
"""
return float_min + (pix / pix_max * (float_max - float_min))
assert scale(100, 200, -2.0, 1.0) == -0.5
assert scale(100, 200, -1.5, 1.5) == 0.0
assert scale(100, 300, -2.0, 1.0) == -1.0
assert scale(25, 300, -2.0, 1.0) == -1.75
De tekenende functies¶
Deze horen in mandelbrot.py, naast de vier functies hierboven.
# laat deze importregel staan...
from png import *
#
# een testfunctie...
#
def test_fun():
"""Maakt een afbeelding pixel voor pixel en slaat die op als test.png."""
im = PNGImage(300, 200) # maak een afbeelding met width=300, height=200
# Geneste lussen!
for row in range(200): # lust over de rijen met lusvariabele row
for col in range(300): # lust over de kolommen met col
if col == row:
im.plot_point(col, row, (255, 0, 0))
im.save_file()
def we_want_this_pixel(col, row):
"""Geeft True terug als de pixel op col, row getekend moet worden."""
if col % 10 == 0 and row % 10 == 0:
# if col % 10 == 0 or row % 10 == 0:
return True
else:
return False
def test():
"""Laat zien hoe je een PNG-afbeelding maakt en opslaat."""
width = 300
height = 200
image = PNGImage(width, height)
# maak een lus om wat pixels te tekenen
for col in range(width):
for row in range(height):
if we_want_this_pixel(col, row):
image.plot_point(col, row)
# we hebben door alle pixels gelust; nu schrijven we het bestand
image.save_file()
# test()
def mset():
"""Tekent de mandelbrotverzameling als een afbeelding van 300 bij 200 pixels."""
NUM_ITER = 50 # aantal updates
XMIN = -2.0 # de kleinste waarde voor de reële coördinaat
XMAX = 1.0 # de grootste waarde voor de reële coördinaat
YMIN = -1.0 # de kleinste waarde voor de imaginaire coördinaat
YMAX = 1.0 # de grootste waarde voor de imaginaire coördinaat
width = 300
height = 200
image = PNGImage(width, height)
# maak een lus om wat pixels te tekenen
for col in range(width):
for row in range(height):
# Gebruik scale twee keer:
# één keer om het reële deel van c te bepalen (x)
x = scale(col, width, XMIN, XMAX)
# één keer om het imaginaire deel van c te bepalen (y)
y = scale(row, height, YMIN, YMAX)
# DAARNA ken je c toe, kies je n en test je:
c = x + y * 1j
if in_mset(c, NUM_ITER):
image.plot_point(col, row, (255, 175, 0))
else:
image.plot_point(col, row, (0, 0, 0))
# we hebben door alle pixels gelust; nu schrijven we het bestand
image.save_file()
# mset()