Dessiner la fractale de Mandelbrot
Pour commencer ma découverte de displayio, j'ai commencé avec un bitmap et une palette de couleur. La fractale de Mandelbrot est l'objet idéal pour commencer à jouer avec displayio.
Le bitmap reçoit les informations sur les pixels, chaque pixel étant codé par une couleur de 0 à 100. La couleur correspond au temps que met a suite itérée \(z_{n+1}=z_n+c\) à sortir du disque de rayon 2.
La palette associe à chaque numéro de couleur la couleur codée en RVB. La fonction ColorMap() permet de créer un dégradé.
Ensuite, on définit une grille contenant une tuile et on définit un groupe contenant cette grille. Un groupe est ce qui sera affiché à l'écran.
Il ne reste plus qu'à actualiser le bitmap avec les calculs de la fractale et d'afficher l'écran à chaque fois qu'une colonne est calculée.
Méthode : Le programme
Voici le programme complet. La partie Initialisation de l'écran est propre à l'écran que j'utilise. Si vous utilisez un autre écran, il faudra adapter. Cette partie peut être simplifiée si vous utilisez une carte pyPortal ou pyBadge car l'écran est accessible via board.DISPLAY.
import board
import displayio
import busio
#############################
# Initialisation de l'ecran #
#############################
_INIT_SEQUENCE = bytearray(
b"\x01\x80\x96" # SWRESET and Delay 150ms
b"\x11\x80\xff" # SLPOUT and Delay
b"\xb1\x03\x01\x2C\x2D" # _FRMCTR1
b"\xb2\x03\x01\x2C\x2D" # _FRMCTR2
b"\xb3\x06\x01\x2C\x2D\x01\x2C\x2D" # _FRMCTR3
b"\xb4\x01\x07" # _INVCTR line inversion
b"\xc0\x03\xa2\x02\x84" # _PWCTR1 GVDD = 4.7V, 1.0uA
b"\xc1\x01\xc5" # _PWCTR2 VGH=14.7V, VGL=-7.35V
b"\xc2\x02\x0a\x00" # _PWCTR3 Opamp current small, Boost frequency
b"\xc3\x02\x8a\x2a"
b"\xc4\x02\x8a\xee"
b"\xc5\x01\x0e" # _VMCTR1 VCOMH = 4V, VOML = -1.1V
b"\x20\x00" # _INVOFF
b"\x36\x01\xb8" # _MADCTL bottom to top refresh
# 1 clk cycle nonoverlap, 2 cycle gate rise, 3 sycle osc equalie,
# fix on VTL
b"\x3a\x01\x05" # COLMOD - 16bit color
b"\xe0\x10\x02\x1c\x07\x12\x37\x32\x29\x2d\x29\x25\x2B\x39\x00\x01\x03\x10" # _GMCTRP1 Gamma
b"\xe1\x10\x03\x1d\x07\x06\x2E\x2C\x29\x2D\x2E\x2E\x37\x3F\x00\x00\x02\x10" # _GMCTRN1
b"\x13\x80\x0a" # _NORON
b"\x29\x80\x64" # _DISPON
)
displayio.release_displays()
_tft_spi = busio.SPI(clock=board.SCK, MOSI=board.MOSI)
_tft_spi.try_lock()
_tft_spi.configure(baudrate=24000000)
_tft_spi.unlock()
_fourwire = displayio.FourWire(_tft_spi, command=board.A3,
chip_select=board.A2,reset=board.A4)
display = displayio.Display(_fourwire, _INIT_SEQUENCE, width=160, height=128,
rotation=0, backlight_pin=board.A5)
display.auto_brightness = True
#############################
# Dessin d'un bitmap #
#############################
# Definition des constantes
N=100
WIDTH=160
HEIGHT=128
# Echelle
CENTER = (-.7435669, .1314023)
DIAMX = .0022878
#CENTER = (-0.5, 0)
#DIAMX = 3
DIAMY = DIAMX*HEIGHT/WIDTH
XMIN=CENTER[0]-DIAMX/2
XMAX=CENTER[0]+DIAMX/2
YMIN=CENTER[1]-DIAMY/2
YMAX=CENTER[1]+DIAMY/2
dx=(XMAX-XMIN)/WIDTH
dy=(YMAX-YMIN)/HEIGHT
# definition de l'objet bitmap
bitmap = displayio.Bitmap(WIDTH, HEIGHT, N)
# construction de la palette de N couleurs
def ColorMap(p):
sr=0 ; sg=0 ; sb=0;
if (p < 64):
sr=0 ; sg=p*4 ; sb=255;
elif (p < 128):
sr=0 ; sg=255 ; sb=(255-(p-64)*4);
elif (p < 192):
sr=(p-128)*4 ; sg=255 ;sb = 0;
elif (p < 256):
sr=255 ; sg=(256-(p-191)*4) ; sb=0;
return (sr,sg,sb);
palette = displayio.Palette(N)
for i in range(N):
r=255*i//(N-1)
s=ColorMap(r)
palette[i]=s[0]*2**16+s[1]*2**8+s[2]
palette[0]=0
palette[1]=0xffffff
# On construit une grille contenant le bitmap
tile_grid = displayio.TileGrid(bitmap, pixel_shader=palette)
# On cree un groupe contenant la grille
group = displayio.Group()
group.append(tile_grid)
display.show(group)
#############################
# Dessin de Mandelbrot #
#############################
def mandelbrot(x,y,iter):
c=x+y*1j
z=c
i=0
while abs(z)<2 and i<iter:
i+=1
z=z*z+c
return -1 if i>=iter else i
x=XMIN
for xp in range(WIDTH):
y=YMIN
for yp in range(HEIGHT):
bitmap[xp,yp]=mandelbrot(x,y,N-1)+1
y += dy
x += dx
display.refresh_soon()
# Attente
while True:
pass
Complément : Changer de zone
Vous pouvez jouer sur les variables d'échelle pour changer la zone affichée. Pour avoir la fractale de Mandelbrot en entier, voici des paramètres qui conviennent.
# Echelle
CENTER = (-0.5, 0)
DIAMX = 3