Pour ce premier projet de NSI d’art génératif, nous avons décidé de représenter une scène en perspective avec des torii, portails japonais traditionnels symboles majeurs de la culture du pays du soleil levant.
Sommaire
Qu’est-ce qu’un torii ?
Un torii est une porte traditionnelle japonaise, souvent en bois ou en pierre, qui marque l’entrée d’un sanctuaire shintoïste. Symboliquement, le torii représente la frontière entre le monde terrestre et le monde spirituel : en passant sous cette porte, on entre dans un espace sacré. Ce symbole est profondément lié à la spiritualité japonaise et au respect de la nature et des divinités dans cette religion.
Le Script
Pour ce projet nous avons décidé de découper chaque partie principale en une fonction distincte : le sol, le fond, les escaliers, la forme d’un torii et l’effet de perspective, nous permettant de travailler indépendamment sur chaque partie et de bien les séparer. A la fin chacune des fonctions est appelées dans un ordre méticuleusement choisi afin de donner le résultat souhaité.
Composition du script
A présent nous allons analyser le script étape par étape afin de mieux comprendre son cheminement.
from turtle import * from random import randint try: from PIL import Image pillow_installed = True except: print("Oops! - ModuleNotFoundError: No module named 'PIL' - RTFM :") print("https://nsi.xyz/py2png") pillow_installed = False titre = "Fushimi Inari - construite avec turtle" title(titre+" | Imene S. Marie GS") setup(1280, 720) speed(0) hideturtle() flash = True if flash: wn = Screen() wn.tracer(0)
Pour ce faire nous utilisons le module Turtle ainsi que la fonction Randint du module Random. Le script inclut une vérification pour s’assurer que le module PIL est bien installé, essentiel pour exporter une image créer avec Turtle; Si PIL n’est pas trouvé, un message d’erreur apparaît avec un lien vers la page d’installation du module, sans interrompre l’exécution du script. Ensuite, nous définissons le titre de la fenêtre pour afficher le rendu final, ajustons sa taille
Commençons par la première fonction : le sol.
from turtle import * from random import randint def sol(): penup() goto(-720, 0) pendown() color("#E8E9F3") begin_fill() fillcolor("#E8E9F3") for _ in range(4): forward(2000) right(90) end_fill() penup()
Pour le sol afin de rester dans la sobriété et éviter la surcharge de couleur, nous avons opté pour un sol d’un gris clair uni remplit avec fill_rect
rappelant des rochers. Le script consiste à créer un rectangle puis de le remplir de gris.
def escaliers(): color("black") penup() goto(-220, -320) pendown() forward(500) penup() goto(-210, -256) pendown() forward(440) penup() goto(-200, -205) pendown() forward(420) penup() goto(-190, -164) pendown() forward(390) penup() goto(-165, -132) pendown() forward(345) penup() goto(-155, -106) pendown() forward(325) penup() goto(-140, -85) pendown() forward(295) penup() goto(-130, -67) pendown() forward(275) penup() goto(-120, -53) pendown() forward(255) penup() goto(-110, -42) pendown() forward(235) penup() goto(-100, -33) pendown() forward(220) penup() goto(-95, -26) pendown() forward(210) penup() goto(-90, -20) pendown() forward(200) penup() goto(-85, -16) pendown() forward(190) penup() goto(-80, -12) pendown() forward(180) penup() goto(-75, -9) pendown() forward(170) penup() goto(-70, -12) pendown() forward(160) penup() goto(-65, -9) pendown() forward(150) penup() goto(-60, -9) pendown() forward(140) penup() goto(-55, -9) pendown() forward(130) penup() goto(-50, -9) pendown() forward(120) penup() goto(-45, -9) pendown() forward(110) penup() goto(-40, -9) pendown() forward(100)
Cette fonction dessine des marches d’escalier en grande partie grâce a la fonction goto()
, en commençant par une ligne longue en bas et en réduisant progressivement la longueur à chaque marche supérieure . Chaque marque a un point de départ et une longueur spécifiques, qui diminuent au fur et à mesure qu’on se rapproche du centre de l’image.
list1 = ["#308E30","#31572C", "#4F772D", "#90A955", "#ECF39E"] def fond(): for i in range(9999): penup() goto(randint(-730,720), randint(-10,720)) pendown() color(list1[i%5]) rcercle = randint(5,10) begin_fill() circle(rcercle) end_fill() penup()
Pour le fond, afin de représenter une forêt, la fonction fond()
dessine plusieurs cercles remplis de couleurs aléatoires tirées de list1, en choisissant des positions et des tailles aléatoires pour chaque cercle. Elle utilise un grand nombre de répétitions (9999) pour couvrir la surface de l’écran.
def dessiner_rectangle(largeur, hauteur, couleur): fillcolor(couleur) begin_fill() for _ in range(2): forward(largeur) left(90) forward(hauteur) left(90) end_fill()
Pour rendre l’utilisation plus simple et rapide d’une des fonctions principales torii()
, nous avons créer la fonction dessiner_rectangle()
ayant pour but de seulement dessiner un rectangle de la couleur, largeur et hauteur souhaitées.
Ce qui nous amène à la fonction suivante torii() :
def torii(x, y, largeur, hauteur): penup() goto(x, y) pendown() color("black", "red") dessiner_rectangle(largeur * 0.1, hauteur, "red") penup() goto(x + largeur - largeur * 0.1, y) pendown() dessiner_rectangle(largeur * 0.1, hauteur, "red") penup() goto(x - largeur * 0.1, y + hauteur) pendown() dessiner_rectangle(largeur * 1.2, hauteur * 0.1, "red") penup() goto(x + largeur * 0.1, y + hauteur - hauteur * 0.1) pendown() dessiner_rectangle(largeur * 0.8, hauteur * 0.05, "red") color("black", "black") penup() goto(x - largeur * 0.05, y - hauteur * 0.1) pendown() dessiner_rectangle(largeur * 0.15, hauteur * 0.1, "black") penup() goto(x + largeur - largeur * 0.1, y - hauteur * 0.1) pendown() dessiner_rectangle(largeur * 0.15, hauteur * 0.1, "black")
La fonction torii()
dessine une structure de torii avec des rectangles, en utilisant des dimensions et des positions spécifiques pour chaque élément.
repeter = 8 def gperspective(): x = -115 y = 0 largeur = 25 hauteur = 50 for i in range(repeter): torii(x, y, largeur, hauteur) x -= 20 * (i + 1) y -= 15 * (i + 1) largeur *= 1.5 hauteur *= 1.5
La fonction gperspective()
crée une série de torii en perspective. En répétant et modifiant légèrement les coordonnées et dimensions des torii à chaque étape. On obtient un effet de perspective, où chaque torii semble être plus loin et plus grand que le précédent grâce aux étapes largeur*= 1.5 et hauteur *= 1.5 consistant à créer un torii 1.5 fois plus grand que le précédent.
repeter = 8 def dperspective(): x = 115 y = 0 largeur = 25 hauteur = 50 for i in range(repeter): torii(x, y, largeur, hauteur) x += +15 * (i + 1) ** 0.5 y += -30 * (i + 1) **0.5 largeur *= 1.5 hauteur *= 1.5 penup() goto(-60, 0) pendown()
La fonction dperspective()
est similaire à gperspective(),
mais elle crée une série de torii en perspective dans une direction différente. Plutôt que de déplacer chaque torii vers la gauche et le bas, cette fonction les déplace vers la droite et le bas.
sol() fond() escaliers() dperspective() gperspective() done()
Et enfin, nous avons appelées les différents fonctions dans un ordre défini afin d’obtenir le résultat attendu.
if flash: wn.update() image = getcanvas() nom_du_fichier_sans_extension=titre+"_"+hex(randint(2**30+2**25,2**30+2**25+2**24-1))[2:] image.postscript(file=nom_du_fichier_sans_extension+".ps", colormode='color') try: psimage = Image.open(nom_du_fichier_sans_extension+".ps") psimage.load(scale=2) psimage_resized = psimage.resize((1280, 720)) psimage.save(nom_du_fichier_sans_extension+".png") print(nom_du_fichier_sans_extension+".png", psimage.size, "sauvegardé dans le dossier") except: if not pillow_installed: print("Oops! - ModuleNotFoundError: No module named 'PIL' - RTFM :") print("https://nsi.xyz/py2png") else: print("Oops! - 'ghostscript' not installed- RTFM :") print("https://nsi.xyz/py2png") exitonclick()
Cette toute dernière parti du script n’a aucun impacte sur le résultat final, c’est pour exporter l’image finale au format .png. En effet, le script comprend une suite de commandes permettant de sauvegarder une image générée par turtle en .png. D’abord, l’image est créée au format .ps puis elle est convertie en .png avec un nom aléatoire (cela permet d’éviter de remplacer les anciennes images avec un nom similaire).