Étiquette : turtle

Art

Paysage japonais

Un paysage où un monument de la culture japonaise se mélange avec un fond naturel est magnifique. Et bien que le Japon soit le pays du soleil, levant nous allons le mettre en valeur avec, cette fois-ci, la lune, à travers des montagnes et des torii. Ces derniers symbolisent un portail entre l’enceinte sacrée et l’environnement profane. C’est pour cette raison qu’il y en a à l’entrée de certains sanctuaires.

Organisation du script

Notre script sera expliqué par étape, de l’arrière plan au premier. La fonction goto sera beaucoup utilisée afin de faire des tracés contrôlés ainsi que pensize() pour la largeur du tracé du stylo, color() pour choisir la couleur du crayon, circle() pour faire un cercle et for i in range pour faire des boucles.

L’arrière-plan

from turtle import*    
pensize (42)    
color("#FFFFFF")

a = -40   
col = ["#FFFFFF","#9BF7F7","#41F9FF","#00CDFF","#008FFF","#0059FF","#003AFF", "#4D00FF","#33079A", "#000000"]    
nb_col = len(col)    
color("#FFFFFF")   
goto(0, 50)    
circle(40)

a = 0  

for i in range (0,10,1):
    goto(0, 40-a)
    color(col[i%nb_col])
    circle(40+a)
    a = a +30
    goto(0, 40-a)
    circle(40+a)
    a = a +30
    goto(0, 40-a)
    circle(40+a)
    a = a +40

Ici, nous montrons que notre script est importé de Turtle, ce module nous permettant de contrôler un crayon pour tracer diverses formes géométriques.

Le fond de notre code n’est pas centré mais c’est fait exprès. Nous avons donc mis la taille du crayon à 42 avec la fonction : pensize (42), ensuite a = -40 nous a servis à déplacer le centre du cercle de base, soit, dans notre cas de le décaler vers la haut. Puis nous avons listé les différentes couleurs utilisées dans tous ces cercles avec col = [ ]. Le goto(0, 50) nous emmènera ensuite aux coordonnées données (donc (0, 50)) puis tracera des cercles de différentes tailles et de différentes couleurs grâce à la fonction cercle circle(40) et à la boucle for i in range (0,10,1):.

Les premières montagnes

color("#42392C")
goto(0, -80)
goto(100, 90)
goto(150,80)
goto(230,150)
goto(270,250)
goto(300,150)
goto(500,20)
goto(580,30)
goto(630,10)
goto(640,-40)
goto(0,-80) 

goto(0, -40)
goto(100,50)
goto(120,40)
goto(200,100)
goto(320,250)
goto(500,30)
goto(580,-10)
goto(630,20)
goto(640,-80)
goto(0,-70) 

goto(0, -40)
goto(120,40)
goto(200,80)
goto(320,230)
goto(500,00)
goto(580,00)
goto(630,000)
goto(640,-60)
goto(0,-50) 

goto(0, -40)
goto(120,33)
goto(200,60)
goto(320,210)
goto(500,00)
goto(580,00)
goto(630,000)
goto(640,-40)
goto(0,-20) 

goto(0, -40)
goto(120,20)
goto(200,50)
goto(320,190)
goto(500,00)
goto(580,00)
goto(630,000)
goto(640,-30)
goto(0,-10) 

goto(0, -40)
goto(120,00)
goto(200,20)
goto(320,170)
goto(500,00)
goto(580,00)
goto(630,000)
goto(640,-10)
goto(0,-00) 

goto(0, -40)
goto(120,00)
goto(200,10)
goto(320,160)
goto(580,00)
goto(630,000)
goto(640,-10)
goto(0,-00)  

goto(320,70)
goto(500,50)
goto(320,60)
goto(320,40)
goto(320,50)
goto(320,30) 

goto(0,-10)
goto(-200,50)
goto(-300,10)
goto(-430,160)
goto(-500,15)
goto(-600,250)
goto(-600,-10)

Nous comprenons ici que les goto sont et seront à l’honneur de ce script ! Ils sont simples à utiliser et donc à comprendre. La couleur des premières montagnes, elle, est encore une fois définie par color(« #42392C »).

Voici le résultat de tous ces goto ! Nous avons un début de montagne avec quelques imperfections mais pas d’inquiétudes ! Ce script fonctionne par plan donc comme un pochoir. Ici, les goto ont donc servis à diriger le stylo d’un point à un autre jusqu’à ce que nous ayons ce résultat

Encore des montagnes

color("#6F6556")
goto(0, 0)
goto(80,40)
goto(120,00)
goto(200,10)
goto(430,200)
goto(630,0)
goto(0,-00)

goto(0, 0)
goto(200,0)
goto(430,180)
goto(630,0)

goto(0, 0)
goto(200,0)
goto(430,160)
goto(630,0)

goto(0, 0)
goto(200,0)
goto(430,150)
goto(630,0)

goto(0, 0)
goto(200,0)
goto(400,150)
goto(630,0)

goto(0, 0)
goto(200,0)
goto(400,140)
goto(630,0)

goto(0, 0)
goto(200,0)
goto(400,130)
goto(630,0)

goto(0, 0)
goto(200,0)
goto(400,120)
goto(630,0)

goto(0, 0)
goto(200,0)
goto(400,110)
goto(630,0)

goto(0, 0)
goto(200,0)
goto(400,100)
goto(630,0)

goto(0, 0)
goto(200,0)
goto(400,90)
goto(630,0)

goto(0, 0)
goto(200,0)
goto(400,80)
goto(630,0)

goto(0, 0)
goto(200,0)
goto(400,70)
goto(630,0)

goto(0, 0)
goto(200,0)
goto(400,60)
goto(630,0)

goto(0, 0)
goto(200,0)
goto(400,60)
goto(630,0)

goto(0, 0)
goto(200,0)
goto(400,50)
goto(630,0)

goto(0, 0)
goto(200,0)
goto(400,40)
goto(630,0)

goto(0, 0)
goto(200,0)
goto(400,40)
goto(630,0)

goto(0, 0)
goto(200,0)
goto(400,30)
goto(630,0)

goto(0, 0)
goto(200,0)
goto(400,20)
goto(630,0)

goto(0, 0)
goto(200,0)
goto(400,10)
goto(630,0)

goto(0,0)
goto(0,-10)
goto(-200,30)
goto(-300,00)
goto(-400,150)
goto(-500,5)
goto(-600,200)
goto(-600,-10)
goto(0,0)

Ces montagnes sont faites de la même manière que les premières : le changement de couleur avec color(« #6F6556 ») et les goto ! Voyons maintenant le résultat en image…

Et voilà nos montagnes finies ! Mais il reste encore quelques étapes pour donner un sens à notre titre.

Le sol bleu

up()
goto(0,-400)
down()
col = ["#000000","#33079A","#4D00FF", "#003AFF", "#0059FF","#008FFF", "#00CDFF", "#41F9FF","#9BF7F7", "#FFFFFF","#9BF7F7","#41F9FF","#00CDFF","#008FFF","#0059FF","#003AFF","#4D00FF","#33079A","#000000"]
nb_col = len(col) 
recup = 0
k = -50
for i in range (0,50):
    color(col[i%nb_col])
    for i in range (0,3):
        k += 40
        goto(1000-k,-35)
        goto(1300-k,-500)

Comme pour l’arrière-plan, les couleurs sont définies grâce à col = [ ].

Avec l’image, nous pouvons plus facilement comprendre la présence de la boucle for i in range (0,50) qui nous a aidé à répéter tous les traits positionnés en diagonale pour nous éviter de les faire un à un avec des goto par exemple !

Les torii

pensize(42)
up()
goto(160,-220)
down()

color("#FF7000")
goto(160,100)
goto(-160,100)
goto(-160,-220)
goto(-160,100)
goto(-220,100)
goto(220,100)
goto(160,100)
goto(160,160)
goto(160,100)
goto(-160,100)
goto(-160,160)
goto(-220,160)
goto(220,160)

pensize(25)
up()
goto(80,-150)
down()

color("#E76E00")
goto(80,20)
goto(-80,20)
goto(-80,-150)
goto(-80,20)
goto(-120,20)
goto(120,20)
goto(80,20)
goto(80,60)
goto(80,20)
goto(-80,20)
goto(-80,60)
goto(-120,60)
goto(120,60)

pensize(12)
up()
goto(40,-120)
down()

color("#CB6100")
goto(40,-30)
goto(-40,-30)
goto(-40,-120)
goto(-40,-30)
goto(-60,-30)
goto(60,-30)
goto(40,-30)
goto(40,-10)
goto(40,-30)
goto(-40,-30)
goto(-40,-10)
goto(-60,-10)
goto(60,-10)

pensize(6)
up()
goto(20,-100)
down()

color("#A95100")
goto(20,-60)
goto(-20,-60)
goto(-20,-100)
goto(-20,-60)
goto(-30,-60)
goto(30,-60)
goto(20,-60)
goto(20,-50)
goto(20,-60)
goto(-20,-60)
goto(-20,-50)
goto(-30,-50)
goto(30,-50)

Voici le code de nos torii. A chaque nouveau pensize( ), il y en a un nouveau ! Nous avons d’abord le placement du crayon avec up( ), goto( ) et down( ) dans cet ordre là. Cela permet de se déplacer en décidant quand nous voulons écrire.

Cette fois-ci, l’image est sans le fond pour mieux observer le choix de couleur ainsi que les tailles décroissantes.

Le résultat final

Et enfin, notre résultat ! Nous avons également rajouté deux ligne, une verte et une marron pour montrer le début des montagnes mais ces lignes servent aussi à cacher la délimitation qu’il y avait pour les traits droits en diagonale.

Télécharger le .py

Art

Miata: une route de nuit

Il s’agit d’un projet d’art génératif réalisé en utilisant principalement le module turtle de python . Nous avons décider de générer une Mazda mx-5 aussi appelée Miata sur une route de nuit avec des étoiles générées aléatoirement.

Le script

On commence par importer les modules dont on a besoin pour la suite tout en définissant la taille de l’image grâce au module pillow

from turtle import *
from random import randint
try:
    from PIL import *
    pillow_installed = True
except:
    print("Oops! - ModuleNotFoundError: No module named 'PIL' - RTFM :")
    print("https://nsi.xyz/py2png")
    pillow_installed = False
# Uniquement des lettres, des chiffres, un tiret. Rien d'autre.
titre = "MIATA"
# Définir le titre de la fenêtre de turtle + propagande ^^
title(titre+" | Au lycée, la meilleure spécialité, c'est la spé NSI")
# definir la taille de la fenêtre en 720p (Largeur, Hauteur)
# La tortue part du centre, au point de coordonnées (0,0)
setup(800, 700)
# La tortue va à la vitesse du lièvre et active sa cape d'invisibilité
speed(0)
hideturtle()

Image de fond

On génère ensuite l’image en commençant par le fond

On commence par le ciel de nuit et les étoiles

def star():

     pensize(3)
     seth(randint(0,360))
     e = randint(2,6)
     color("#F2F3CF")
     penup()
     goto(randint(-400,400),randint(85,350))
     pendown()
     for i in range(5):
        forward(e)
        right(142)

speed(0)
pensize(10000)
hideturtle()
color("#07073C")
forward(10)

for i in range(18):
    star()
penup()
goto(-250,300)
pendown()
pensize(2)
begin_fill()
seth(210)
color("#BFC298")
for i in range(

On commence par définir la fonction star() qui nous sert a générer une étoile d’une taille aléatoire a une position elle aussi aléatoire dans la zone qui sera le ciel pour éviter qu’elle finisse cachée par les autres éléments qui seront générés par la suite. Ensuite on fait un fond bleu nuit qui prend l’entièreté de l’écran en mettant une taille de crayon très grande et on génère 18 étoiles en utilisant une boucle qui répète la fonction star() puis on fait un croissant de lune en faisant des boucles donnant des arrondis . Ainsi on obtient cela:

on continue en ajoutant une forêt qui sera derrière la voiture

goto(-400,75)
pendown()
pensize(2)
color("#2C4D20")
begin_fill()
for i in range(3):
    seth(45)
    forward(77)
    right(90)
    forward(70)
    seth(45)
    forward(60)
    right(90)
    forward(80)
    seth(45)
    forward(50)
    right(90)
    forward(43)
right(45)
forward(460)
right(90)
forward(810)
right(90)
forward(455)
end_fill()

Ce code nous permet de générer des triangles de 3 tailles différentes que l’on va remplir fin de donner l’illusion d’une forêt dense en utilisant un vert foncé

On continue en réalisant la route

seth(0)
goto(-450,-125)
pensize(30)
color("#373639")
forward(900)
penup()

goto(-400,-175)
pendown()
pensize(2)
begin_fill()
color("#262527")
forward(800)
right(90)
forward(200)
right(90)
forward(800)
right(90)
forward(200)
end_fill()

goto(-400,-180)
pensize(7)
seth(0)
for i in range(4):
    color("white")
    forward(100)
    penup()
    forward(100)
    pendown()

Ce code nous permet de faire un grand trait de couleur grise pour représenter la barrière puis il génère un grand rectangle qui représente la route en y ajoutant des bandes blanches, créant ainsi une route.

La voiture

On passe ensuite à la partie la plus importante du script: la voiture

def phares():
    left(30)  
    fillcolor('gray')
    begin_fill()
    left(80)
    color('yellow')
    pensize(4)
    forward(25)
    pensize(1)
    color('gray')
    right(120)
    forward(30)
    right(130)
    forward(30)
    end_fill()
    forward(-31)
    color('red')
    pensize(4)
    right(50)
    forward(32)
    forward(-32)
    color('red')
    right(125)
    pensize(1)
    pendown()
def jantes():
    color('gray')
    begin_fill()
    fillcolor('black')
    circle(30)
    end_fill()
    forward(5)
    left(90)
    forward(10)
    pendown()
    begin_fill()
    fillcolor('silver')
jantes()

Cette partie nous permet de faire l’avant de la voiture en définissant la fonction pour faire une roue composée d’un pneu et d’une jante, inspiré des jantes BBS et ainsi que la fonction qui servira à faire le phare avant

pensize(1)
color('black')
fillcolor('red')
for i in range (35):
    forward(1)
    right(0.75)
right(75)

forward(50)
right(90)
for i in range(169):
    forward(0.5)
    left(1)
right(94)
forward(20)
end_fill()
right(85)
forward(52)
right(163)
penup()
forward(63)
pendown()
jantes()

Résultat final

Il s’agit de la fin du code pour l’image, terminant la Miata en faisant l’habitacle composé du toit de la voiture et d’une fenêtre puis l’arrière de la voiture en rappelant la fonction définie plus tôt afin de faire la seconde roue

Pour conclure on met la dernière partie de code pour exporter l’image en fichier.png

# ============== GENERER DES IMAGES AUTOMATIQUEMENT ==============

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:]

# Génère un fichier .ps
image.postscript(file=nom_du_fichier_sans_extension+".ps", colormode='color')

# Ouvre le fichier .ps et génère le fichier .png


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()

Télécharger le projet

Projets

Cinéma: Matrix et le binaire

« Are you telling me I can dodge bullets ? » Neo, The matrix. Cette citation représente la base de notre projet dans lequel est présenté le personnage Neo au visage hélicoïdal stoppant les balles sur un fond de chiffres binaires aléatoirement positionnés.

I – Le fond

Premièrement, le fond nous semblait être la partie la plus importante du projet. Nous avons donc commencé par poser un fond noir avec les lignes de code suivantes

color('black')
pensize(2000) #peu conventionnel 😅
goto(-635, 350)
forward(700)

Après cela, nous y avons superposé les caractères 1 et 0 que nous avons définis avec le code suivant.

def un():
    pensize(2)
    color('green')
    setheading(60)
    forward(12)
    setheading(270)
    forward(20)

def zero():
    setheading(90)
    circle(8)

Nous avons ensuite créé une suite de boucle pour placer aléatoirement des 1 et des 0 en colonnes. Pour cela, nous avons utilisé le module « random » avec la fonction « random.choice » pour sélectionner aléatoirement un nombre dans une liste prédéfinie, ensuite, une condition nous a permis de placer les chiffres. Pour ordonner ces derniers, une incrémentation aux coordonnées déjà inscrites (définissant la position du premier caractère posé) à la fin de chaque boucle a été nécessaire. Voici le code

y = 330
x = -620
    
for i in range(50):
    penup()
    goto(x, y)
    pendown()
    
    for i in range(20):
        list1 = [1,2]

        if random.choice(list1) == 1: 
            un()
        else:
            zero()
            
        penup()
        goto(x, y - 40 * (i + 1))
        pendown()
        
    x += 25 #incrémentation de la distance entre chaque colonnes (horizontalement)
    

Voici le résultat du fond finalisé :

II – Le personnage, Neo

1 – La main

La main était aussi une partie importante de l’image : elle constitue le point de fuite centrale de l’image, où se dirige toutes les balles. Voici la main, constituée de lignes plus ou moins courtes (doigts) et d’un cercle (paume).

2 – Le corps

Nous avons donc créé le corps d’un homme bâton, avec de simples lignes et un cercle pour la tête. Voici le code :

def corps():
    pensize(5)
    color('white')
    penup()
    goto(0,-70)
    pendown()
    setheading(90)
    left(110)
    forward(180)
    left(25)
    forward(80)
    left(180)
    forward(80)


    setheading(90)
    forward(40)
    right(180)
    forward(150)
    setheading(90)
    right(150)
    forward(90)
    left(180)
    forward(90)
    setheading(90)
    left(150)
    forward(90)
    right(180)
    forward(90)
    setheading(90)
    forward(150)

    right(90)
    circle(50)
    penup()
    setheading(90)
    forward(50)
    pendown()
corp()

Voici le rendu :

3 – La spirale

Pour créer cette spirale, il n’a suffit que de 2 lignes, avec une boucle for :

for i in range(48):
    circle(i,20) # i est donc augmenté a chaque répétition 

Le rendu fut le suivant :

III – Les balles

Pour créer les balles, nous avons créé une fonction, en utilisant les méthodes « begin_fill » et « end_fill » permettant de remplir tout ce que l’on dessine en trait. Voici le code :

def balle():
    pensize(3)
    color('#A9A9A9')
    begin_fill()
    forward(30)
    left(143)
    forward(27)
    left(110)
    forward(15)
    end_fill()
    left(180)
    forward(7)
    color("grey")
    begin_fill()
    circle(10)
    end_fill()

Voici le résultat

Pour créer plus de dynamisme, nous avons opté pour des tirets, encore avec une fonction, appelées (comme les balles) plusieurs fois. Nous avons donc créé une boucle for, se répétant 18 fois :

def tiret():
    for i in range(18):
        pensize(7)
        color("white")
        forward(5)
        penup()
        forward(15)
        pendown()

Pour une balle, nous avons combiné les deux fonctions en les appelant de la sorte :

penup()
left(50)
goto(300,-150) 
pendown()
balle()
penup()
left(90)
forward(30)
pendown()
tiret() 
right(90)

Nous avons répété ce pattern sept fois, en changeant leurs positions (goto).

IV – L’image finale

V – Les problèmes rencontrés

Le seul ‘problème’ qu’on a rencontré fut pour le fond, pour utiliser le module random dans une liste, mais nous avons relu nos exercices sur ce thème et avons facilement trouvé la solution.

VII – Télécharger le .py

Nous vous mettons au défi d’optimiser ce code au maximum, sans changer le rendu.

Art

Le micro BM 800

Pour ce premier projet de NSI d’art génératif, nous avons décidé de représenter un micro, un BM 800 avec le module turtle de python.

La vidéo du projet :

Pourquoi le micro ?

Tout simplement car Mathieu fait de la musique plus précisément des instrumentales et Romain lui fait de l’audiovisuel (photos et vidéos). Le micro qui est indispensable dans ces 2 univers. Nous avons choisi le micro BM 800 car pour débuter c’est l’un des meilleurs micros.

Le projet

Pour en revenir au projet, nous avons décidé de faire un micro. Pour cela nous avons utilisé le module turtle ainsi que le module random.

Structure du script

Pour la structure du script nous avons décidé de découper chaque partie de l’image (fond, albums vinyles, cors du micro, prise XLR et bonnette du micro) pour créer des fonctions et pour organiser le script.

Analyse du script

Nous allons analyser le script :

nous allons commencer par par l’appel des modules et la mise en place de turtle :

from turtle import *
from random import randint

"""
Ce fichier est expliqué ici : https://nsi.xyz/py2png
Un autre tutoriel permet de commencer : https://nsi.xyz/tutoriels/decouvrir-le-module-turtle-de-python/
"""

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

# Uniquement des lettres, des chiffres, un tiret. Rien d'autre.
# https://learn.microsoft.com/fr-fr/windows/win32/fileio/naming-a-file
titre = "micro bm800 - construit avec turtle"

# Définir le titre de la fenêtre de turtle + propagande ^^
title(titre+" | Au lycée, la meilleure spécialité, c'est la spé NSI")

# definir la taille de la fenêtre en 720p (Largeur, Hauteur)
# La tortue part du centre, au point de coordonnées (0,0)
setup(1280, 720)

# La tortue va à la vitesse du lièvre et active sa cape d'invisibilité
speed(0)
hideturtle()

"""NOUVEAUTE 2023 :
Pour un tracé instantané, sans aucun délai,
il suffit d'affecter la valeur True à la variable "flash" (False par défaut)
mais cela rend le débuggage moins facile
Merci @bebertii 
"""

flash = True # False par défaut, on peut mettre True sinon, ou mieux 0x2A
if flash:
    wn = Screen()
    wn.tracer(0)

Ensuite pour le fond nous avons utilisé une fonction qui se nomme background-color. Nous avons défini avec la couleur bleu marine en hexadécimal.

def fond():
  bgcolor("#03224c")

Ce qui nous donne :

Après nous avons fait le corps du micro avec quelques valeurs tel que la couleur, la longueur et la largeur du rectangle. Puis nous avons défini une position à laquelle le corps du micro va se positionner, nous avons tracé un rectangle noir, puis nous avons tracé un trapèze pour représenter le bout du micro.

import turtle

ht()

def corpmicro():
    t = turtle.Turtle()

    col = ("#000000")
    l = 100
    la = 200


    t.goto(-100,0)
    t.fillcolor(col)
    t.begin_fill()
    t.ht()

    for i in range(2):
        t.forward(l)
        t.right(90)
        t.forward(la)
        t.right(90)

    t.end_fill()
    t.begin_fill()
    t.penup()
    t.rt(90)
    t.forward(la)
    t.pendown()
    t.left(45)
    t.forward(40)
    t.left(45)
    t.forward(44)
    t.left(45)
    t.forward(40)
    t.end_fill()

Ce qui nous donne avec le fond :

Après cela, pour la prise XLR, nous avons réalisé une fonction prise XLR puis nous avons tracé un rectangle gris et nous lui avons donné une position finale.

def prisexlr(): 
    p = turtle.Turtle()
    col3 = ("#c4c4c4")
    l7 = 44
    la6 = 20

    p.ht()
    p.penup()
    p.goto(-72,-228)
    p.pendown()
    p.fillcolor(col3)


    p.begin_fill()
    for i in range(2):
        p.forward(l7)
        p.right(90)
        p.forward(la6)
        p.right(90)
    p.end_fill()

Ce qui nous donne avec le fond et le corps du micro :

Ensuite pour les 2 albums vinyles, nous avons fait 2 fonctions distincts pour chacun des 2 albums vinyles dans lesquels nous avons rentré les même valeurs tel que les couleurs et le rayon des 2 cercles qui compose l’album vinyle ainsi que la longueur du carré. Ensuite nous avons juste modifié les positions des cercles et carrés.

1er album vinyle :

def albumvinyle():

    a = turtle.Turtle()
    col4 = ("#000000")
    col5 = ("#2f4f4f")
    col6 = ("#f9429e")
    l8 = 80
    r = 35
    r2 = 35/2

    a.penup()
    a.goto(-400,300)
    a.pendown()
    a.fillcolor(col5)
    #carton de l'album
    a.begin_fill()
    for i in range (4):
        a.forward(l8)
        a.right(90)

    a.end_fill()

    #vinyle
    a.penup()
    a.goto(-360,225)
    a.pendown()
    a.fillcolor(col4)


    a.begin_fill()
    a.circle (r2)

    a.end_fill()

    #centre du vinyle
    a.penup()
    a.goto(-360,242)
    a.pendown()
    a.fillcolor(col6)
    a.ht()

    a.begin_fill()

2e album vinyle :

def albumvinyle2():

    a = turtle.Turtle()
    col4 = ("#000000")
    col5 = ("#2f4f4f")
    col6 = ("#f9429e")
    l8 = 80
    r = 35
    r2 = 35/2

    a.penup()
    a.goto(360,-220)
    a.pendown()
    a.fillcolor(col5)
    #carton de l'album
    a.begin_fill()
    for i in range (4):
        a.forward(l8)
        a.right(90)

    a.end_fill()

    #vinyle
    a.penup()
    a.goto(400,-295)
    a.pendown()
    a.fillcolor(col4)


    a.begin_fill()
    a.circle (r2)

    a.end_fill()

    #centre du vinyle
    a.penup()
    a.goto(400,-277)
    a.pendown()
    a.fillcolor(col6)
    a.ht()

    a.begin_fill()
    a.circle (r2)

    a.end_fill()

Ce qui nous donne avec le fond, le corps du micro et la prise XLR :

De plus pour la bonnette du micro, nous avons défini un rectangle noir pour faire ressortir le quadrillage gris de la bonnette.

def bonettefond():
    #fond permetant de faire un quadrillage noir
    b = turtle.Turtle()
    col2 = ("#000000")
    l2 = 125
    la2 = 150

    b.penup()
    b.goto(-225/2,150)
    b.pendown()
    b.fillcolor(col2)
    b.ht()

    b.begin_fill()
    for i in range(2):
        b.forward(l2)
        b.right(90)
        b.forward(la2)
        b.right(90)
    b.end_fill()

Ensuite pour la grille de la bonnette, nous avons fait le quadrillage de la bonnette pour cela nous avons réalisé une fonction qui va permettre de faire des lignes horizontales et verticales.

def bonettegrille():

    g = turtle.Turtle()
    col3 = ("#c4c4c4")
    l3 = 150
    la3 = 4
    l4 = 125

    g.penup()
    g.goto(-230/2,150)
    g.pendown()
    g.fillcolor(col3)
    g.begin_fill()
    g.ht()
    #grille horizontale
    for i in range(16):
        g.right (90)
        g.forward(l3)
        g.left(90)
        g.forward(la3)
        g.left(90)
        g.forward(l3)
        g.right(90)
        g.forward(la3)

    g.right(90)
    #grille verticale
    for i in range(19):
        g.right (90)
        g.forward(l4)
        g.left(90)
        g.forward(la3)
        g.left(90)
        g.forward(l4)
        g.right(90)
        g.forward(la3)

    g.end_fill()

Et pour finir pour les barres de la bonnette, nous avons créer une fonction qui va nous permettre de faire 4 rectangles de longueurs et de largeurs différentes et aussi de positions différentes pour créer les barres de la bonnette.

def barrebonette():
    bo = turtle.Turtle()
    col3 = ("#c4c4c4")
    l5 = 127
    la4 = 25
    l6 =6
    la5 =145


    bo.penup()
    bo.goto(-230/2,145)
    bo.pendown()
    bo.fillcolor(col3)
    bo.ht()
    #première barre horizontale
    bo.begin_fill()
    for i in range(2):
        bo.forward(l5)
        bo.right(90)
        bo.forward(la4)
        bo.right(90)
    bo.end_fill()

    bo.goto(-230/2,25)
    #deuxième barre horizontale
    bo.begin_fill()
    for i in range(2):
        bo.forward(l5)
        bo.right(90)
        bo.forward(la4)
        bo.right(90)

    bo.end_fill()

    bo.goto(-232/2,145)

    #première barre vertical
    bo.begin_fill()
    for i in range(2):
        bo.forward(l6)
        bo.right(90)
        bo.forward(la5)
        bo.right(90)

    bo.end_fill()

    bo.goto(10,145)
    #deuxième barre vertical
    bo.begin_fill()
    for i in range(2):
        bo.forward(l6)
        bo.right(90)
        bo.forward(la5)
        bo.right(90)

    bo.end_fill()

Ce qui nous donne avec juste la bonnette et le fond :

De plus, nous avons une fonction très importante qui sert pas à dessiner quelque chose mais elle rassemble toutes les fonctions afin de les mettre dans le bonne ordre. Donc cela nous a permis de faire chacun nos fonctions chez nous et les mettre en commun.

def immagemicro():
    fond()
    corpmicro()
    bonettefond()
    bonettegrille()
    barrebonette()
    prisexlr()
    albumvinyle()
    albumvinyle2()



immagemicro()

L’image finale

Art

Un arbre fractale

La fractale est couramment sélectionnée comme thème pour la création d’images en raison de sa capacité à produire des motifs d’une complexité infinie et captivante. Cette fusion entre l’art et les mathématiques permet de représenter de manière créative la beauté des structures complexes, qu’elles soient naturelles ou urbaines.

Projet

Donc pour le projet nous avons décider de faire une fractale (l’arbre de Pythagore) sur un dégradé et faire un petit soleil sur le coté haut droit de l’image. Pour cela nous avons mis les script grâce à la bibliothèque turtle.

Le script

Donc pour faire le script nous nous aidons de la bibliothèque turtel. Mais tous les structure construise sont faite grâce à « def ». Nous avons donc du tous les appels a la fin un part un de manier logique et ordonné.

Le script en detailer

from turtle import *
import turtle
from random import randint
from PIL import Image
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

# Uniquement des lettres, des chiffres, un tiret. Rien d'autre. https://learn.microsoft.com/fr-fr/windows/win32/fileio/naming-a-file
titre = "Fractale - Un arbre fractaleà"

# Définir le titre de la fenêtre de turtle + propagande ^^
title(titre+" | Au lycée, la meilleure spécialité, c'est la spé NSI")

# definir la taille de la fenêtre en 720p (Largeur, Hauteur, abscisse départ, ordonnée du départ)
setup(1280, 720) 
colormode(255) 
speed(0)

Tout d’abord « setup(1280, 720) » aident à configurer la fenêtre graphique Turtle pour votre dessin fractal, en lui donnant une taille spécifique (1280×720 pixels)

Puis colormode(255) serre à modifié le mode de couleur pour le rendre plus lisible (de 0 à 255 pour RGB)

Et enfin speed(0) serre à régler la vitesse de dessin pour qu’elle soit la plus rapide possible (vitesse 0).

Le fond:

def fond():
    penup()
    rciel = 0
    gciel = 0 
    bciel = 0
    hauteur = -360
    goto(-642,-358)
    pendown()
    while hauteur != 360:
        pencolor(round(239 + rciel), round(200 + gciel), round(209 + bciel))
        forward(1280)
        hauteur += 1
        goto(-640, hauteur)
        rciel += (-29/180)
        gciel += (2/45)
        bciel += (7/720)

Cette fonction « fond() » dessine un ciel en dégradé en utilisant une boucle « while » pour créer des bandes horizontales de couleur qui simulent un dégrade sur un ciel . Les composantes de couleur « rciel » « gciel » « bciel » changent progressivement à mesure que la hauteur augmente, créant un effet de transition de couleur réaliste.

La fractale arbre

def arbre(n,longueur):
    down()
    if n==0:
        color('green')
        forward(longueur) # avance
        backward(longueur) # recule
        color('#3f1905')
    else:
        width(n)
        forward(longueur/3) #avance
        left(angle) # tourne vers la gauche de angle degrés
        arbre(n-1,longueur*2/3)
        right(2*angle) # tourne vers la droite de angle degrés
        arbre(n-1,longueur*2/3)
        left(angle) # tourne vers la gauche de angle degrés
        backward(longueur/3) # recule

La fonction arbre à deux paramètres « n" et « longueur » pour contrôler le niveau de récursion et la longueur de la branche.

La condition « if n == 0 » permet de voir le cas de base dais que la profondeur de récursion atteint zéro.

En résumé, ce code utilise la récursion pour faire une fractale d’arbre, créant des branches qui se divise en sous-branches. Le niveau de récursion contrôle le détail de l’arbre, et la longueur de la branche diminue à chaque niveau, formant ainsi une structure d’arbre sur la base d’une fractale.

Le soleil

def soleil():
    speed(0)
    i = 0
    goto(-590, 305)
    while i < 200:
        down()
        color('#FF8C00')
        right(90)
        forward(55)
        right(180)
        forward(55)
        right(90)
        circle(5, 2)
        i = i + 1

Ce processus est répété jusqu’à ce que i atteigne 200 créant une série de formes qui se superposent pour former une figure qui ressemble à un soleil.

fond()

hideturtle() # cache la tortue
up() # lève le stylo
right(90) # tourne de 90 degrés vers la droite 
forward(300) # avance de 300 pixels
left(180) # fait un demi-tour
goto(0,-350)
angle = 50
color('#3f1905')
arbre(11,700) # exécute la macro

hideturtle() # cache la tortue
up() # lève le stylo
soleil()

On appelle tout les fonction maintenant

Vers le PNG

image = getcanvas()
Fractale=titre+"_"+hex(randint(2**30+2**25,2**30+2**25+2**24-1))[2:]

# Génère un fichier .ps
image.postscript(file=Fractale+".ps", colormode='color')

# Ouvre le fichier .ps et génère le fichier .png
psimage = Image.open(Fractale+".ps")
psimage.save(Fractale+".png")

Téléchargement du programme

Art

Paysage : un coucher de soleil

Les couchers de soleils vous fascinent ? Vous êtes ici au bon endroit pour apprendre à créer des levers et couchers de soleil de votre choix sans devoir attendre le crépuscule. Je vous explique en détail mon script qui permet de générer une image avec le module turtle en python.

Les prémices du projet

Dans un premier temps, j’ai longtemps réfléchi à ce que je pouvais faire pour le projet libre de cette fin d’année. Je me suis décidée à refaire une image générée par le module turtle en python. Effectivement, notre tout premier projet de l’année était le même, néanmoins j’avais tout de suite commencé très fort en faisant des fractales. Certains vous diront que cela est facile, mais mon niveau de début d’année ne me permettait pas de tout comprendre. Ce qui m’a frustré. Je me suis donc décidée à refaire une image avec mon niveau actuel (qui est encore débutant !) pour pouvoir gérer la conception de A à Z.

Par conséquent, le script et l’image peuvent vous paraître assez simple. Cependant, j’ai souhaité m’inspirer du projet https://nsi.xyz/art/urbanisme-la-skyline-de-new-york/ qui se rapproche du flat design (ils l’expliquent très bien dans leur article). Le rendu final est donc très épuré et très simple.

Le code

Pour concevoir cette image, j’ai procédé par étapes pour créer le code. En découpant mon image, en plusieurs parties.

Le fond

Tout d’abord, j’ai codé le fond c’est-à-dire le coucher de soleil. L’espace utilisé est découpé en morceau rectangulaire. Puis pour chaque rectangle est associé une couleur. Je définis donc en premier mes neuf couleurs. Ensuite, j’utilise une boucle for, qui prend à chaque itération de la boucle la couleur suivante contenu dans la liste couleur.

def coucherdesoleil():
    couleur = ["#FFBA08",
               "#FAA307",
               "#F48C06",
               "#E85D04",
               "#DC2F02",
               "#D00000",
               "#9D0208",
               "#6A040F",
               "#370617"]
    penup()
    goto(640,-300)
    setheading(180)
    pendown()
    
    for fond in couleur: # ChatGPT m'a aidé sur cette ligne et la ligne suivante
        color(fond)
        begin_fill()
        forward(1280)
        right(90)
        forward(74)
        right(90)
        forward(1280)
        end_fill()
        
        left(180)

Le résultat :

Les étoiles

Puis, je crée une fonction qui permet de dessiner des étoiles. Elle prend en paramètre la longueur des branches, et l’emplacement de l’étoile, tout en définissant sa couleur.

def etoile(longueur, x, y):
    goto(x,y)
    pencolor("#DF7B0A")
    pendown()
       
    left(50)
    for i in range(5):
        forward(longueur)
        right(144)
    
    penup()

Je souhaitais que les étoiles se situent seulement en haut du ciel, tout en se positionnant de façon aléatoire, et de taille aléatoire. Ainsi par la boucle for , dix étoiles sont créées avec des paramètres précis (taille et position) mais de façon aléatoires.

for i in range(10):
    etoile(randint(5,15), randint(-630,630), randint(293, 350))

Le résultat :

Le soleil

Ensuite, le script exécute la fonction créant le soleil. Il se positionne à des coordonnées précises, je positionne le curseur en direction du haut de l’image : setheading(90), puis j’utilise la fonction prédéfinie du cercle, en indiquant la taille du rayon et si je souhaite un demi-cercle ou un cercle.

def soleil():
    goto(-115, -285)
    fillcolor("#FFC93E")
    begin_fill()
    setheading(90)
    circle(70, 180)
    end_fill()

Le résultat :

Les montagnes

Pour cette fonction, je me suis inspirée voir même j’ai repris la boucle créant l’ondulation des montagnes de mon ancien projet https://nsi.xyz/art/jardins-foret-enneigee/. Afin de créer une montagne, il faut lui donner comme paramètres d’entrée sa position initiale et finale (pour qu’ensuite elle puisse être remplie), la couleur, la direction, l’angle et la longueur des vagues.

De plus, pour varier la taille des montagnes, j’ai utilisé un test conditionnel afin de modifier l’inclinaison en fonction de sa position initiale.

Enfin, la boucle for permet de créer une vague, qui se répètent trois fois, formant une ondulation.

def rocher(x1, y1, x2, y2, couleur, direction, angle, vague1, vague2):
    fillcolor(couleur)
    pencolor(couleur)
    goto(x1,y1)
    if direction == 0:
        setheading(0)
        right(angle)
    else:
        setheading(direction)
        left(angle)   
    
    begin_fill()

    pendown()
    for i in range (3): # boucle repris de mon ancien projet https://nsi.xyz/art/jardins-foret-enneigee/
        for i in range (5):
            forward(vague1)
            right(2)
        for i in range (5):
            forward(vague2)
            left(2)
    
    goto(x2,y2)
    
    penup()
    end_fill()

Le résultat final

Les problèmes rencontrés et leurs solutions

Le premier problème était que les montagnes ne s’arrêtaient pas toutes à la même ligne, il y avait donc des débordements en dehors du cadre. Ma solution a été de créer une ligne blanche repassant sur ces débordements. Je pense qu’il y avait sûrement une solution ou un bout de code permettant de stopper les boucles quand elles arrivaient à un certain endroit, mais j’ai préféré utiliser cette méthode.

Le deuxième problème a été l’emplacement des étoiles. Effectivement, au début vingt étoiles étaient créées avec des emplacements aléatoires, par conséquent il y avait des superpositions. J’ai donc décidé de réduire le nombre, afin que les étoiles aient moins de chance d’obtenir la même position.

Le troisième problème n’en est pas vraiment un, mais cela était plutôt un souhait que je n’ai pas réussi à effectuer. En effet, je souhaitais faire un beau dégradé pour le coucher de soleil. J’en avais vu un sur cet article https://nsi.xyz/art/perspective-un-paysage-synthwave/ j’ai longtemps essayé de comprendre la fonction et j’ai même demandé à ChatGPT, mais sans succès. J’ai donc décidé de ne pas copier coller un code que je ne comprenais pas et j’ai laissé le coucher de soleil actuel.

Mes sources

J’ai principalement codé avec mes connaissances, les cours de NSI et les anciens projets disponibles sur le site https://nsi.xyz/. Toutefois, j’ai eu besoin de faire des recherches et j’ai utilisé ChatGPT à plusieurs reprises pour qu’il me montre mon erreur lorsque je ne comprenais pas le message d’erreur ou quand je ne comprenais pas tout à fait les explications que je trouvais sur internet.

Conclusion

En conclusion, je suis très fière de mon image. Même si son codage est effectué avec les base de la programmation et peut paraître facile. J’ai pris plaisir à programmer, comprendre, corriger toute seule mes erreurs, afin de concevoir une image propre à mes connaissances et à mes envies.

Télécharger le .py

Si vous souhaitez générer l’image et l’utiliser comme fond d’écran n’hésitez pas à télécharger le fichier ci-dessous.

Art

Perspective : un paysage Synthwave

Dans le cadre de la 5ème édition du dispositif “Regards de Géomètre”, nous avons décidé dans le thème « Perspective » de produire un paysage synthwave.

Origines de la Synthwave

Avant tout la synthwave est un genre musical électronique ayant émergé dans les années 2000/2010 qui s’inspire d’éléments des années 80. Et c’est justement dans les clips de ces musiques que l’on va retrouver ce type d’image.

Pour en savoir plus nous vous conseillons cette vidéo qui explique brièvement les origines.

Le Projet

Revenons donc au projet. Pour ce projet nous avons donc décidé de produire une image d’un paysage synthwave. Pour cela nous utilisons le module turtle ainsi que le module random, le module turtle est utilisé pour produire l’image est le module random est utilisé pour les étoiles de l’image où la taille et leur position est générée aléatoirement nous avons également utilisé le script permettant d’exporter une image générée par turtle en .png que vous pouvez retrouver ici.

Structure du script

Pour la structure du script nous avons décidé de découper chaque partie de l’image (pavage, fond, étoiles, soleil, ville et montagnes) afin de créer des fonctions et à la fin nous les avons toutes appelées dans un ordre précis pour que les différentes parties de l’image soit dans leur plan respectif.

Analyse du script

Nous allons donc analyser le script.

Commençons par l’appel des modules et la mise en place de turtle.

from turtle import *
from random import randint
# vérification des modules importés
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 = "Perspective - Un paysage Synthwave"
title(titre+" | Au lycée, la meilleure spécialité, c'est la spé NSI")
setup(1280, 720) # définit la taille de la fenêtre
colormode(255) # permet l'utilisation de couleurs rgb
speed(0) #Remplaçable par tracer(2) (10x plus rapide) mais si il est utilisé des lignes du pavage peuvent manquer
hideturtle() #dissimule la tortue

On appelle les fonctions turtle, random avec pour random uniquement randint et on utilise une partie du script « exporter une image générée par turtle » pour vérifier que l’utilisateur a bien installé le module PIL et dans le cas contraire un message d’erreur s’affichera et lui donnera un lien pour installer le module et tout ça sans que le script ne s’arrête. Après la vérification on met en place le titre de la fenêtre qui va affiché le rendu ainsi que sa taille. Enfin on définit le type de couleurs utilisées (R,G,B), la vitesse de la tortue, et on dissimule la tortue (c’est plus joli).

Commençons par la première fonction : le fond

def fond():
    penup()
    rciel = 0
    gciel = 0 
    bciel = 0
    hauteur = -360
    goto(-642,-358)
    pendown()
    while hauteur != 360:
        pencolor(round(239 + rciel), round(41 + gciel), round(209 + bciel))
        forward(1280)
        hauteur += 1
        goto(-640, hauteur)
        rciel += (-29/180)
        gciel += (2/45)
        bciel += (7/720)

Pour le fond on aurait pu utiliser une fonction qui crée un rectangle et qui le remplit avec fill_rect, cependant la couleur dans ce cas est uni ce qui ne nous intéresse pas. Nous avons donc produit un script qui fait un fond dégradé qui fait avancer la tortue sur une ligne d’un pixel de large et à la fin de cette ligne la tortue est envoyé grâce à un goto à la ligne d’après et qui ajoute la différence de chaque couleur (rouge,vert et bleu) entre la couleur de début du dégradé et la couleur de fin. Tout ceci est arrondi car turtle n’est pas compatible avec des arguments à virgule (pour la fonction pencolor en tout cas).

Par la suite la fonction qui produit les étoiles a été codée :

def etoile():
    for i in range(90):
        penup()
        goto(randint(-720,720), randint(0,360))
        pendown()
        pencolor(255, 255, 255)
        lcercle = randint(1,3)
        fillcolor('white')
        begin_fill()
        circle(lcercle)
        end_fill()

Pour les étoiles on définit aléatoirement leur position sur la moitié haute de l’image, on les met en blanc, on définit aussi aléatoirement la taille de l’étoile et on créer l’étoile avec sa position, et sa taille en aléatoire puis on refait ce processus 90 fois pour avoir 90 étoiles.

Ensuite nous avons le soleil (Le script affiché n’est qu’une petite partie du script total du soleil car il est très long et qu’il se répète, il est donc inutile de commenter la suite) :

def soleil():
    penup()
    liste1 = [10,7,5,4,3,3,3,3,2,2,2,2,2,2,2,1,2,1,2,1,1,2,1,1,1,1,2,1,1,1]
    liste2 = [1,1,1,0,1,1,1,1,1,0,1,1,1,0,1,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0]
    pliste1 = 0
    pliste2 = 0
    rsoleil = 0
    gsoleil = 0
    bsoleil = 0
    lsoleil = 8
    hauteur = 30
    goto(0,30)
    pendown()
    for i in range(15):
        pencolor(round(255 + rsoleil), round(23 + gsoleil), round(226 + bsoleil))
        forward(lsoleil)
        backward(2*lsoleil)
        hauteur += 1
        lsoleil += liste1[pliste1]
        pliste1 += 1
        goto(0, hauteur)
        rsoleil += (0)
        gsoleil += (114/101)
        bsoleil += (-203/202)
    forward(lsoleil)
    backward(2*lsoleil)
    penup()

Pour le soleil nous réutilisons le script du dégradé, cependant nous l’avons modifier pour que le point d’origine de la tortue soit au centre du rectangle et que la longueur de chaque ligne soit défini par une liste (ce qui permet de faire un cercle en prenant les longueur d’un cercle utilisable en pixel art). Pour ce qui est des endroits ou le soleil est coupé la tortue fait le tracé mais on a utilisé la fonction penup() qui fait que la tortue ne dessine plus.

Après nous avons la fonctions des montagnes (Encore une fois le script n’est pas complet car il se répète encore 3 fois après.) :

def montagne():
    #montagne derrière la première
    penup()
    goto(-480,0)
    fillcolor(110, 27, 188)
    begin_fill()
    for i in range(3):
        forward(250)
        left(120)
    end_fill()
    
    goto(-480,0)
    pencolor(51, 210, 246)
    ymontagne = 10
    for i in range(11):
        pendown()
        goto(-355,ymontagne)
        goto(-230,0)
        penup()
        goto(-480,0)
        ymontagne += 20

Pour le script des montagnes nous avons utilisé le script pour faire des triangles équilatéraux retrouvable ici. Et ensuite nous avons utilisé un ‘for i in range’ pour faire des goto enchaîné pour faire les lignes des montagnes.

Ensuite nous avons les fonctions de la ville. Pourquoi les fonctions car il y a une fonction pour chaque bâtiment différent ainsi qu’une fonction finale qui définit l’ordre des bâtiments.

def bat1():
    penup()
    rbat = 0
    gbat = 0 
    bbat = 0
    hauteur = 0
    pendown()
    xturtle, yturtle = pos()
    while hauteur != 72:
        pencolor(round(125 + rbat), round(35 + gbat), round(216 + bbat))
        forward(42)
        hauteur += 1
        goto(xturtle, hauteur)
        rbat += (-5/3)
        gbat += (-7/15)
        bbat += (-72/25)
    forward(42)
    penup()
    right(90)
    forward(72)
    left(90)

Pour le bâtiment 1 il y a un dégradé (toujours le même script) puis on fait que la tortue finisse le bâtiment en bas à droite de ce dernier pour pouvoir enchainer les bâtiments.

fun fact : Au début nous n’avions pas prévu les quelques lignes à la fin pour que la tortue puisse enchaîner les bâtiments sans que les fonctions des bâtiments aient besoin d’être modifiés ce qui nous a amené à avoir tous les bâtiments qui se chevauchaient.

def ville():
    penup()
    goto(-320,0)
    bat3(), bat2(), bat1(), bat4() ,bat3(), bat4(), bat3(), bat2(), bat1(), bat2(), bat1(), bat3(), bat1(), bat4(), bat2(), bat1(), bat3(), bat1(), bat4(), bat3()

Et à la fin on a fait la fonction ville qui appelle dans l’ordre choisi les bâtiments. Le goto permet de définir où commence le premier bâtiment, les autres se mettent juste après le premier sans se chevaucher ni laisser un espace.

Par la suite nous avons le pavage (très long aussi, il sera donc coupé) :

def pavage():
    colormode(255)
    pensize(5)
    speed(0)
    rciel = 0
    gciel = 0 
    bciel = 0
    hauteur = -360
    penup()
    goto(-640,-360)
    pendown()
    while hauteur != 0:
        pencolor(round(15 + rciel), round(4 + gciel), round(76 + bciel))
        forward(1280)
        hauteur += 1
        goto(-640, hauteur)
        rciel += (91/180)
        gciel += (1/36)
        bciel += (7/18)

Pour le début du pavage on retrouve encore le script du dégradé mais avec les couleurs modifiées.

pencolor(229, 123, 240)
    #Lignes au dessus du pavage
    pensize(4),penup(),goto(-640,0),pendown(),goto(640,0),pensize(2),penup(),goto(-640, 0),pendown()
    #lignes gauche
    penup(),goto(-20.00,0),pendown(),goto(-60.00,-360.00),penup(),goto(-60.00,0),pendown(),goto(-180.00,-360.00),penup(),goto(-100.00,0),pendown(),goto(-300.00,-360.00),penup(),goto(-140.00,0),pendown(),goto(-420.00,-360.00),penup(),goto(-180.00,0),pendown(),goto(-540.00,-360.00),penup(),goto(-220.00,0),pendown(),goto(-660.00,-360.00),penup(),goto(-260.00,0),pendown(),goto(-780.00,-360.00),penup(),goto(-300.00,0),pendown(),goto(-900.00,-360.00),penup(),goto(-340.00,0),pendown(),goto(-1020.00,-360.00),penup(),goto(-380.00,0),pendown(),goto(-1140.00,-360.00),penup(),goto(-420.00,0),pendown(),goto(-1260.00,-360.00),penup(),goto(-460.00,0),pendown(),goto(-1380.00,-360.00),penup(),goto(-500.00,0),pendown(),goto(-1500.00,-360.00),penup(),goto(-540.00,0),pendown(),goto(-1620.00,-360.00),penup(),goto(-580.00,0),pendown(),goto(-1740.00,-360.00),penup(),goto(-620.00,0),pendown(),goto(-1760.00,-360.00)
    #lignes droites
    penup(),goto(20,0),pendown(),goto(60.00,-360.00),penup(),goto(60.00,0),pendown(),goto(180.00,-360.00),penup(),goto(100.00,0),pendown(),goto(300.00,-360.00),penup(),goto(140.00,0),pendown(),goto(420.00,-360.00),penup(),goto(180.00,0),pendown(),goto(540.00,-360.00),penup(),goto(220.00,0),pendown(),goto(660.00,-360.00),penup(),goto(260.00,0),pendown(),goto(780.00,-360.00),penup(),goto(300.00,0),pendown(),goto(900.00,-360.00),penup(),goto(340.00,0),pendown(),goto(1020.00,-360.00),penup(),goto(380.00,0),pendown(),goto(1140.00,-360.00),penup(),goto(420.00,0),pendown(),goto(1260.00,-360.00),penup(),goto(460.00,0),pendown(),goto(1380.00,-360.00),penup(),goto(500.00,0),pendown(),goto(1500.00,-360.00),penup(),goto(540.00,0),pendown(),goto(1620.00,-360.00),penup(),goto(580.00,0),pendown(),goto(1740.00,-360.00),penup(),goto(620.00,0),pendown(),goto(1760.00,-360.00)
    #Lignes horizontales
    penup(),goto(-640, -300),pendown(),goto(640, -300),penup(),goto(-640, -240),pendown(),goto(640, -240),penup(),goto(-640, -190),pendown(),goto(640, -190),penup(),goto(-640, -140),pendown(),goto(640, -140),penup(),goto(-640, -100),pendown(),goto(640, -100),penup(),goto(-640, -70),pendown(),goto(640, -70),penup(),goto(-640, -40),pendown(),goto(640, -40),penup(),goto(-640, -15),pendown(),goto(640, -15),

On a par la suite énormément de goto afin de faire le quadrillage du pavage.

Pour produire l’image finale nous avons les appels des différents fonctions à la fin :

#appel de toutes les fonctions
fond(), etoile(), soleil(), montagne(), ville(), pavage()

Et pour exporter l’image finale en .png il y a la suite du script pour exporter une image générée par turtle en .png utilisé au début du script.

#enregistrement de l'image finale avec vérification des modules importés
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()

Le script va donc générer une image en .ps et la convertir en .png avec un nom généré aléatoirement pour éviter que à chaque fois que vous générez une image l’image soit écrasée

Télécharger le .py

L’image finale

Art

Astronomie : Un semblant de liberté

« C’est dur, oui, il a tant cherché sa place dans l’univers : société, nature sauvage, vie luxueuse,… mais rien de tout ça ne lui convenait. Se tournant vers le ciel, c’était peut-être parmi les étoiles que se trouvait sa place… »


Introduction

À l’aide du module Turtle, on va pouvoir créer une image en python, animée ou non.
Aujourd’hui, ce sera alors plutôt un dessin que nous générerons par notre code, de plus, celle-ci sera différente à chaque exécution !
Nous allons alors décortiquer des parties de celui-ci afin de le comprendre, si ce n’est pas déjà le cas ! 😉


Une mise en bouche qui nous prépare

colormode(255)
color(5,9,44)
goto(-640,0)
pensize(1000)
forward(1000)

Ce bloc de code permet de préparer le dessin en y installant un fond bleu nuit rappelant l’espace.
La couleur est définie dans les 2 premières lignes, ensuite on se rend à des coordonnées hors du champ de vision puis on trace un trait très épais.


Des fonctions par-ci, des fonctions par-là

def etoile():
    pensize(2)
    couleur = randint(0,3)
    if couleur == 0:
        color(250, 137, 25)
    else:
        color(247,247,36)
    for _ in range(5):
        forward(10)
        right(144)

Le bloc de code suivant est une fonction, elle nous permet de définir une suite d’instructions qu’on peut utiliser par la suite.
Elle dessine une étoile tout en utilisant un autre module permettant d’utiliser l’aléatoire, à l’aide de celui-ci et de structure conditionnelles, on choisit aléatoirement entre 2 couleurs pour l’étoile.
Puis, on la trace à l’aide d’une boucle bornée. 😵

def position_aleatoire():
    penup()
    x = randint(-640,640)
    y = randint(-320,320)
    goto(x,y)
    pendown()

Cette seconde fonction diffère de la 1ère par son utilité-même : elle permet de choisir une position aléatoire.
La fonction génère aléatoirement des coordonnées dans un intervalle défini, ici, celle de la fenêtre puis elle s’y rend.

for _ in range(42):
    position_aleatoire()
    type_etoile = randint(0,2)
    if type_etoile == 0:
        etoile_2()
    else:
        etoile()

C’est alors que la magie entre en scène, on manipule les fonctions précédemment créées afin de produire un splendide ciel étoilé !
On se rend à un endroit aléatoire grâce à la 2ème fonction puis on dessine une étoile grâce à la 1ère fonction (et une autre produisant un autre type d’étoile), et ceci 42 fois !! 😱


Des éléments de décoration


D’autres éléments constituant l’image proviennent de fonctions, prenons ici l’exemple de la fusée :

def fusee():
    left(55)
    penup()
    goto(-100,-40)
    pendown()
    corps_fusee()
    for i in range(2):
        penup()
        goto(-125+i*275/100*25,-50-i*5/2*20)
        pendown()
        moteur()
    for i in range(2):
        penup()
        goto(-15+i*35*135/100,-65/2+i*50*135/100)
        pendown()
        hublot()
    right(30)
    penup()
    goto(15,125)
    pendown()
    toit()


On peut voir une différence notable avec les fonctions précédentes, cette fonction est elle-même constituée de fonctions : « corps_fusee » ; « moteur » ; « hublot » et « toit ».
Et comme dit plus tôt, on utilise et manipule ces fonctions, par exemple en les utilisant plusieurs fois dans une boucle, en définissant un angle au préalable,… et ça ne s’arrête pas là ! on pourrait très bien utiliser la fonction définissant la fusée afin de lui donner une autre utilité !

C’est alors en usant de fonctions, de boucles et de structures conditionnelles qu’on peut facilement produire une œuvre avec le module Turtle, mais tout cela ne peut se réaliser qu’avec de la pratique, car comme j’ai dit : « C’est en programmant que l’on devient programmeur ».

L’image finale

Télécharger le .py

Art

Urbanisme : La skyline de New York

Pour ce premier projet en classe de première NSI nous avons choisi comme thème l’urbanisme. Nous avons souhaiter créer un projet original. Ce programme a pour but de réaliser un rendu graphique qui se rapproche au maximum du flat design. 

C’est quoi le flat design ?

Petit point de culture générale : Très brièvement le flat design est un style graphique caractérisé par le minimalisme et la simplicité des éléments présents sur le rendu. On ne cherche pas à faire à être dans le détail avec des ombres, des effets 3d… mais à être dans la simplicité avec une recherche en amont. Le flat design est aujourd’hui utilisé dans différentes catégories telle que l’illustration ou encore dans l’UI design où il consistera à obtenir un rendu fluide et ergonomique pour l’utilisateur. Un très grand artiste français qui utilise le flat design est Malika Favre voilà quelques exemples de créations qu’il a pu réaliser :

Les Recherches

Dans un premier temps pour réaliser ce projet nous avons dû faire différentes recherches sur internet. Les recherches finies, nous avons créer un moodboard pour mettre nos idées au claire et pour avoir de l’inspiration.

Nous avons sélectionné une image de la Skyline sur internet et nous l’avons directement modifiée sur Photoshop pour ne pas avoir de soucis avec les droits d’auteur.

Skyline/ Photoshop

Dans un second temps, nous nous sommes mis d’accord pour ne pas créer une simple Skyline mais bien plus. Notre point de départ est un couché de soleil avec des couleurs pastelles pour obtenir un rendu idéal qui se rapproche du flat design.

Une fois que nous étions d’accord sur les détails de notre projet, nous avons commencé le script phyton. Nous nous sommes divisés le travail en deux groupes :

  • Skyline : Noah / Henry
  • Ciel : Constance

Le code en entier

from turtle import *
from random import randint

#Lever de soleil

colormode(255)
bgcolor("#ffb399")

def disque(rayon, x, y, couleur=(1, 1, 1)):
    penup()
    goto(x, y-rayon)
    pendown()
    pencolor(couleur)
    fillcolor(couleur)
    begin_fill()
    circle(rayon)
    end_fill()
    
x, y = (0,-120)
radius = (500)
color = ("#ffc6b3")
disque(radius, x, y, color) 

x, y = (0,-120)
radius = (400)
color = ("#ffd9cc")
disque(radius, x, y, color) 
    
x, y = (0,-120)
radius = (300)
color = ("#ffece6")
disque(radius, x, y, color)     

x, y = (0,-120)
radius = (200)
color = ('white')
disque(radius, x, y, color)   


def arrondi_gauche():
    for i in range(180):
        left(1)
        forward(7/45)
        
def arrondi_droit():
    for i in range(180):
        right(1)
        forward(7/100)


def nuage():
    speed(10)
    pendown()
    width(2)
    pencolor("#ffffb3")
    fillcolor("#ffffb3")
    begin_fill()
    forward(210)
    arrondi_gauche()
    forward (21)
    arrondi_droit()
    forward(14)
    arrondi_gauche()
    forward(70)
    arrondi_droit()
    forward(56)
    arrondi_gauche()
    forward(28)
    arrondi_droit()
    forward(14)
    arrondi_gauche()
    forward(20)
    for i in range(90):
        right(1)
        forward(7/50)
    for i in range(90):
        left(1)
        forward(7/45)
    forward(35)
    for i in range(90):
        left(1)
        forward(7/45)
    for i in range(90):
        right(1)
        forward(7/50)
    forward(21)
    arrondi_gauche()
    forward(14)
    arrondi_droit()
    forward(49)
    arrondi_gauche()
    forward(42)
    arrondi_droit()
    forward(56)
    arrondi_gauche()
    forward(7)
    arrondi_droit()
    forward(42)
    arrondi_gauche()
    forward(10)
    end_fill()

penup()
goto(-450,-40)
nuage()

penup()
goto(300,55)
nuage()

penup()
goto(-50,200)
nuage()

#Skyline

pensize(3)
def building1(longueur,largeur, couleur=(1,1,1)):
    pendown()
    pencolor(couleur)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    right(90)
    forward(longueur/1.5)
    left(90)
    forward(longueur/2)
 
def building2(longueur, largeur, couleur=(1,1,1)):
    etage(longueur, largeur/5)
    etage(longueur/2 , largeur/5)
    etage(longueur/3 , largeur/5)
    left(80)
    forward(longueur/2)

def etage(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)

def etage_inverse(longueur, largeur, couleur=(1,1,1)):
    forward(largeur)
    left(270)
    forward(longueur)
    left(90)
def building2_inverse(longueur, largeur, couleur=(1,1,1)):
    right(160)
    forward(longueur/2)
    left(80)
    etage_inverse(longueur/3, largeur/5)
    etage_inverse(longueur/2 , largeur/5)
    etage_inverse(longueur, largeur/5)

def building3(longueur, largeur, couleur=(1,1,1)):
   forward(longueur/3)
   left(90)
   forward(longueur)
   right(90)
   forward(largeur)
   right(90)
   forward(longueur/4)
   left(90)
   forward(largeur)
   left(90)
   forward(longueur/5)
   right(90)
   forward(largeur)
   right(90)
   forward(longueur/2)
   
def building4(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur/3)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    left(90)
    forward(longueur-30)
    right(90)
    forward(largeur+25)
    right(90)
    forward(longueur+20)
    
def building5(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    right(90)
    forward(longueur/2)
    left(45)
    forward(longueur/2)
    right(225)
    forward(longueur/3)
    right(90)
    forward(largeur+5)
    right(90)
    forward(longueur+30)
    
def building6(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur)
    left(90)
    forward(longueur)
    right(30)
    forward(longueur/8)
    left(30)
    forward(30)
    right(30)
    forward(longueur/8)
    left(30)
    forward(60)

def building6_reverse(longueur, largeur, couleur=(1,1,1)):
    left(180)
    forward(60)
    left(30)
    forward(longueur/8)
    right(30)
    forward(30)
    left(30)
    forward(longueur/8)
    right(30)
    forward(longueur)
    left(90)
    forward(largeur)
    
def building7(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    left(90)
    forward(longueur/3)
    right(90)
    forward(largeur)
    right(90)
    forward(longueur-130)
    left(90)
    forward(largeur)
    right(90)
    forward(longueur-50)
    left(35)
    forward(largeur*2)
    right(35)
    forward(longueur-75)


def building8(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    right(90)
    forward(longueur/2)
    left(35)
    forward (largeur)
    right(35)
    forward(longueur-20)
       
    
    
penup()
fillcolor("#80586D")
begin_fill()
goto(-630,-350)
goto(-630,-300)
building1(60,30, couleur=("#80586D"))
building2(150,80 , couleur=("#80586D"))
building2_inverse(150,80 , couleur=("#80586D"))
building3(120,30, couleur=("#80586D"))
building4(100,40, couleur=("#80586D"))
building5(80,25, couleur=("#80586D"))
building6(275,50, couleur=("#80586D"))
building6_reverse(275,50, couleur=("#80586D"))
right(90)
building4(90,30, couleur=("#80586D"))
building7(165,35, couleur=("#80586D"))
left(90)
building3(170,35, couleur=("#80586D"))
building8(150,45, couleur=("#80586D"))
pendown()
goto(630,-350)
goto(-630,-350)
end_fill()



penup()
fillcolor("#01343D")
begin_fill()
left(90)
goto(-620,-350)
building1(60,30, couleur=("#01343D"))
building2(150,80 , couleur=("#01343D"))
building2_inverse(150,80 , couleur=("#01343D"))
building3(120,30, couleur=("#01343D"))
building4(100,40, couleur=("#01343D"))
building5(80,25, couleur=("#01343D"))
building6(275,50, couleur=("#01343D"))
building6_reverse(275,50, couleur=("#01343D"))
right(90)
building4(90,30, couleur=("#01343D"))
building7(165,35, couleur=("#01343D"))
left(90)
building3(170,35, couleur=("#01343D"))
building8(150,45, couleur=("#01343D"))
pendown()
goto(-630,-350)
end_fill()

Le Fond

def disque(rayon, x, y, couleur=(1, 1, 1)):
    penup()
    goto(x, y-rayon)
    pendown()
    pencolor(couleur)
    fillcolor(couleur)
    begin_fill()
    circle(rayon)
    end_fill()
    
x, y = (0,-120)
radius = (500)
color = ("#ffc6b3")
disque(radius, x, y, color) 

x, y = (0,-120)
radius = (400)
color = ("#ffd9cc")
disque(radius, x, y, color) 
    
x, y = (0,-120)
radius = (300)
color = ("#ffece6")
disque(radius, x, y, color)     

x, y = (0,-120)
radius = (200)
color = ('white')
disque(radius, x, y, color)   


def arrondi_gauche():
    for i in range(180):
        left(1)
        forward(7/45)
        
def arrondi_droit():
    for i in range(180):
        right(1)
        forward(7/100)
Fond

Pour réaliser le fond, j’ai adapté la fonction disque des exemples donnés afin de faire un dégradé de disques partant d’un peu plus bas que le centre et du plus clair au plus foncé. De cette manière, le disque au centre est blanc et représente donc le Soleil. De plus, les disques autour forment un dégradé de couleurs modélisant le levé du Soleil dans le ciel.

Les nuages

def nuage():
    speed(10)
    pendown()
    width(2)
    pencolor("#ffffb3")
    fillcolor("#ffffb3")
    begin_fill()
    forward(210)
    arrondi_gauche()
    forward (21)
    arrondi_droit()
    forward(14)
    arrondi_gauche()
    forward(70)
    arrondi_droit()
    forward(56)
    arrondi_gauche()
    forward(28)
    arrondi_droit()
    forward(14)
    arrondi_gauche()
    forward(20)
    for i in range(90):
        right(1)
        forward(7/50)
    for i in range(90):
        left(1)
        forward(7/45)
    forward(35)
    for i in range(90):
        left(1)
        forward(7/45)
    for i in range(90):
        right(1)
        forward(7/50)
    forward(21)
    arrondi_gauche()
    forward(14)
    arrondi_droit()
    forward(49)
    arrondi_gauche()
    forward(42)
    arrondi_droit()
    forward(56)
    arrondi_gauche()
    forward(7)
    arrondi_droit()
    forward(42)
    arrondi_gauche()
    forward(10)
    end_fill()

penup()
goto(-450,-40)
nuage()

penup()
goto(300,55)
nuage()

penup()
goto(-50,200)
nuage()

Pour rajouter un effet naturel au ciel, on a décidé d’ajouter des nuages avec une couleur et une forme adaptée au moment de la journée du levé de Soleil. J’ai donc crée une fonction nuage qui comprend également deux autres fonctions pour arrondir chaque bosse des nuages. De cette façon, le script est bien plus court. Pour faire les arrondis, j’ai d’abord fait le script d’un cercle, puis je l’ai adapté dans chacune des fonctions afin que sa largeur puisse varier.

La Skyline

def building1(longueur,largeur, couleur=(1,1,1)):
    pendown()
    pencolor(couleur)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    right(90)
    forward(longueur/1.5)
    left(90)
    forward(longueur/2)
 
def building2(longueur, largeur, couleur=(1,1,1)):
    etage(longueur, largeur/5)
    etage(longueur/2 , largeur/5)
    etage(longueur/3 , largeur/5)
    left(80)
    forward(longueur/2)

def etage(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)

def etage_inverse(longueur, largeur, couleur=(1,1,1)):
    forward(largeur)
    left(270)
    forward(longueur)
    left(90)
def building2_inverse(longueur, largeur, couleur=(1,1,1)):
    right(160)
    forward(longueur/2)
    left(80)
    etage_inverse(longueur/3, largeur/5)
    etage_inverse(longueur/2 , largeur/5)
    etage_inverse(longueur, largeur/5)

def building3(longueur, largeur, couleur=(1,1,1)):
   forward(longueur/3)
   left(90)
   forward(longueur)
   right(90)
   forward(largeur)
   right(90)
   forward(longueur/4)
   left(90)
   forward(largeur)
   left(90)
   forward(longueur/5)
   right(90)
   forward(largeur)
   right(90)
   forward(longueur/2)
   
def building4(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur/3)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    left(90)
    forward(longueur-30)
    right(90)
    forward(largeur+25)
    right(90)
    forward(longueur+20)
    
def building5(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    right(90)
    forward(longueur/2)
    left(45)
    forward(longueur/2)
    right(225)
    forward(longueur/3)
    right(90)
    forward(largeur+5)
    right(90)
    forward(longueur+30)
    
def building6(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur)
    left(90)
    forward(longueur)
    right(30)
    forward(longueur/8)
    left(30)
    forward(30)
    right(30)
    forward(longueur/8)
    left(30)
    forward(60)

def building6_reverse(longueur, largeur, couleur=(1,1,1)):
    left(180)
    forward(60)
    left(30)
    forward(longueur/8)
    right(30)
    forward(30)
    left(30)
    forward(longueur/8)
    right(30)
    forward(longueur)
    left(90)
    forward(largeur)
    
def building7(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    left(90)
    forward(longueur/3)
    right(90)
    forward(largeur)
    right(90)
    forward(longueur-130)
    left(90)
    forward(largeur)
    right(90)
    forward(longueur-50)
    left(35)
    forward(largeur*2)
    right(35)
    forward(longueur-75)


def building8(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    right(90)
    forward(longueur/2)
    left(35)
    forward (largeur)
    right(35)
    forward(longueur-20)
       
    
    
penup()
fillcolor("#80586D")
begin_fill()
goto(-630,-350)
goto(-630,-300)
building1(60,30, couleur=("#80586D"))
building2(150,80 , couleur=("#80586D"))
building2_inverse(150,80 , couleur=("#80586D"))
building3(120,30, couleur=("#80586D"))
building4(100,40, couleur=("#80586D"))
building5(80,25, couleur=("#80586D"))
building6(275,50, couleur=("#80586D"))
building6_reverse(275,50, couleur=("#80586D"))
right(90)
building4(90,30, couleur=("#80586D"))
building7(165,35, couleur=("#80586D"))
left(90)
building3(170,35, couleur=("#80586D"))
building8(150,45, couleur=("#80586D"))
pendown()
goto(630,-350)
goto(-630,-350)
end_fill()



penup()
fillcolor("#01343D")
begin_fill()
left(90)
goto(-620,-350)
building1(60,30, couleur=("#01343D"))
building2(150,80 , couleur=("#01343D"))
building2_inverse(150,80 , couleur=("#01343D"))
building3(120,30, couleur=("#01343D"))
building4(100,40, couleur=("#01343D"))
building5(80,25, couleur=("#01343D"))
building6(275,50, couleur=("#01343D"))
building6_reverse(275,50, couleur=("#01343D"))
right(90)
building4(90,30, couleur=("#01343D"))
building7(165,35, couleur=("#01343D"))
left(90)
building3(170,35, couleur=("#01343D"))
building8(150,45, couleur=("#01343D"))
pendown()
goto(-630,-350)
end_fill()
New York Skyline

Dans le cas de la Skyline, le principal défi a été d’éviter de reproduire la même chose. Donc pour remédier au problème, nous avons coder de nombreuses fonctions « def » pour initialiser les buildings. Ensuite, il s’agissait surtout de calculer les bâtiments et les étages car ils étaient tous hétérogènes. Enfin, il nous suffisait d’utiliser les fonctions en rentrant les mesures et définir les couleurs puis la Skyline de New York prend vie.

Conclusion

En réalisant ce projet, nous avons étudié l’architecture de New York en analysant les suites logiques de buildings en fonction de leurs tailles par exemple. Nous avons aussi travaillé sur la meilleure façon de représenter un lever de Soleil de manière simple et évidente en regardant des exemples sur des dessins et des photos. En python, on a appris à manipuler les fonctions pour exécuter des scripts sans les réécrire plusieurs fois (avec les arrondis des nuages par exemple). Nous avons aussi du travailler beaucoup avec les couleurs avec les plusieurs plans des buildings qui ont permis de donner du relief à l’image grâce aux couleurs mais aussi avec le dégradé du ciel pour qu’il paraisse naturel. Nous avons aussi du visualiser l’image finale en gardant le meilleur de différentes inspirations et tout calculer pour que l’image ne soit ni trop vide ni trop surchargée d’éléments. Cette réalisation avait pour but d’être esthétique, moderne et simple.4

Télécharger le .py

Si vous voulez l’essayer, vous trouverez le script ci-dessous, mais attention, les nuages prennent énormément de temp à s’exécuter !

Art

Musique : Pink Floyd et son album lumineux

Le choix de la pochette d’album « The Dark Side of the Moon » n’a, d’après les membres du groupe, pas de signification précise. Lassés des photographies chargées ou des collages compliqués, ceux-ci cherchaient un visuel simple et facile à retenir. C’est bien le cas puisque 50 ans après, l’image du spectre lumineux se dispersant à travers un prisme est presque toujours associée au groupe Pink Floyd.

Vidéo de présentation du projet

De la physique à la musique

Lors du feuilletage d’un manuel de physique, l’attention du graphiste des Pink Floyd a été retenue par une photographie en noir et blanc d’un prisme à travers lequel se dispersait la lumière. L’idée lui est alors venue de choisir cette image en guise de pochette d’album.

En physique, un spectre lumineux est le résultat de la décomposition de la lumière par un spectroscope. Il permet d’analyser celle ci grâce aux radiations qui la composent.

Cette image n’est pas sans rappeler les éclairages des concerts où des faisceaux lumineux traversent la scène en se modifiant au contact des musiciens, tel le spectre traversant le prisme.

De la musique à la NSI

Nous avons donc décidé de récréer numériquement cette pochette d’album. Pour ce faire, nous avons utilisé le langage python et l’émulateur Thonny.

Tout d’abord, nous avons instauré le fond de couleur noir en utilisant la fonction bgcolor().

Nous avons ensuite tracé le triangle principal en veillant à le placer au centre. Pour cela, nous avons mis pour point d’abscisse de départ la valeur « -100 » afin que la longueur du triangle soit de « 200 ».

Puis, nous nous sommes penchés sur la partie gauche de notre image en commençant par tirer un trait défini par ses points de coordonnées de départ et d’arrivée.

Effet dégradé à l’intérieur du triangle :

Vient ensuite une partie plus complexe : l’élargissement du trait en dégradé, partant de la couleur initiale du trait pour aller vers le noir de l’arrière plan.

Pour cela, le script effectue des traits en allers-retours (grâce à une boucle for), d’un point défini sur le triangle jusqu’au milieu du triangle. Pour chaque trait, l’opacité (a) diminue au fur et à mesure que le trait se rapproche du milieu du triangle. L’opacité est remise à sa valeur initiale (a=255) avant chaque traçage de trait.

turtle.colormode(255)
for i in range(20):
    penup()
    a = 255
    go to(-40, 100)
    for i in range(41):
        turtle.color(a,a,a)
        pendown()
        turtle.forward(1)
        a += -6
    turtle.right(1)

Et voici le résultat:

Réalisation du triangle et du faisceaux lumineux entrant

Création de l’arc en ciel :

Ensuite, en partant d’un point situé sur la bordure droite du triangle, nous avons créé une boucle for permettant de réaliser les traits de couleur à droite, définis par une liste. Pour que les couleurs attendus soient identiques à celle de la pochette d’album originale, nous avons trouvé leur équivalent en hexadécimal grâce au site « Image Color Picker ».

liste = ["#6f597a","#3476b2","#78ab23", "#f9fc49","#e8b30d","#de2b05",]
goto(63 - 10/6, 81)
turtle.right(12)
turtle.pensize(10)
s=5
for i in range(6):
    turtle.color(liste[i%6])
    pendown()
    turtle.forward(355 + 0.1*i)
    penup()
    goto(58 - 10/6*i, 80 + s + 4*i)
    turtle.left(1)
    s+=-1
Script initial avec ajout de l’arc en ciel

Enfin, nous avons reproduit les commandes de lecture, situées dans la partie inferieure de notre rendu visuel, en utilisant encore une fois des boucles for pour créer des formes géométriques telles que des rectangles ou des triangles.

Afin de créer un effet visuel plus esthétique nous avons aussi intégré les fonctions begin_fill() et end_fill() qui permettent de colorer l’intérieur de formes géométriques telles que le « bouton pause » par exemple.

Nous vous proposons la découverte de notre rendu final ci-dessous, j’espère qu’il vous plaira!

Rendu final du script après exécution

Télécharger le .py :

Pour finir, nous vous partageons l’intégralité de notre projet afin que vous puissiez le découvrir plus en détail !