| |
Les nouvelles technologies pour l’enseignement des mathématiques
Intégration des TICE dans l’enseignement des mathématiques

MathémaTICE, première revue en ligne destinée à promouvoir les TICE à travers l’enseignement des mathématiques.

Théorie des langages et géométrie : la courbe de Sierpinski

En SNT [1], des élèves de Seconde ont été chargés de reproduire les deux dernières figures de l’article de Sierpiński titré « Sur une courbe dont tout point est un point de ramification » (1915). Ils l’ont fait au crayon sur papier pointé, ou à l’aide du module turtle de Python.

Article mis en ligne le 1er juillet 2022
dernière modification le 8 août 2022

par Alain Busser

L’une des courbes fractales les plus connues est celle que Wacław Sierpiński a publiée en 1915 sous le titre « sur une courbe dont tout point est un point de ramification ». Cette courbe est surtout connue sous le nom de triangle de Sierpiński. Or ce n’est pas un triangle (surface), mais bien une courbe.

Pour s’en convaincre, on peut dessiner la courbe avec une « tortue ». Ou plus précisément, une approximation polygonale à 3n côtés. Ce fut fait en Seconde (en Sciences du Numérique et Technologie) durant l’année scolaire 2021-2022.

Licence Creative Commons
Cet article est mis à disposition selon les termes de la Licence Creative Commons Attribution - Partage dans les Mêmes Conditions 2.0 France.

Preuve que c’est une courbe

Pour prouver que la courbe de Sierpiński est bien une courbe, on peut calculer son aire et vérifier que celle-ci est nulle. Soit $4a$ l’aire du triangle initial. On calcule, en fonction de $a$, l’aire totale enlevée à ce triangle [2] :

  1. on enlève un triangle (celui des milieux) d’aire $a$,
  2. puis on enlève 3 triangles, d’aire $\frac{a}{4}$ chacun, soit une aire de $\frac{3a}{4}$,
  3. puis on enlève 9 triangles, dont chacun a pour aire $\frac{a}{16}$, soit une aire de $\frac{9a}{16}$,
  4. etc.

L’aire du domaine enlevé à chaque étape, suit une progression géométrique de raison $\frac{3}{4}$ et de premier terme $a$. Au bout de $n$ étapes, on a enlevé en tout

$a+a\frac{3}{4}+a\frac{9}{16}+...+a\frac{3^n}{4^n} = a\frac{1-\frac{3^{n+1}}{4^{n+1}}}{1-\frac{3}{4}} = 4a(1-\frac{3^{n+1}}{4^{n+1}})$

Or cette suite est la différence entre $4a$ et une suite géométrique de raison inférieure à 1, et qui donc tend vers 0 : à l’infini, l’aire totale enlevée au triangle initial est $4a$ soit l’aire de ce triangle.

La courbe de Sierpiński est d’aire nulle (il s’agit bien d’une courbe).

Documents

En plus de la construction par triangles enlevés, Sierpiński a montré une approximation par polygones permettant de mieux voir qu’il s’agit d’une courbe.

Sierpiński

Voici l’article original de Sierpiński, publié en 1915 (en pleine première guerre mondiale) dans les Comptes rendus de l’Académie des Sciences :

Ce sont les figures 3 à 6 qui montrent ces mystérieux polygones. Mystérieux, car Sierpiński n’explique pas comment on passe d’une étape à la suivante. Or, Sierpiński a par la suite été cryptographe, d’où le titre de l’activité présentée en Seconde : on imagine un code (secret) permettant de construire les polygones...

Sujet du TP

Le sujet suivant a été donné à faire durant presque toute l’année scolaire. Toutes les deux semaines (sauf jour férié, interruption sur l’orientation ou septaine) j’avais la classe en groupes (de 17 ou 18 élèves tout de même) de telle manière que chaque élève était devant un ordinateur avec Python installé, voire sa calculatrice Numworks avec interpréteur Python.

Voici le sujet :

Les élèves qui arrivent en Seconde sont théoriquement déjà familiarisés avec le paradigme de la tortue, qui est à l’origine de Scratch, utilisé au moins en Troisième pour la préparation du DNB. Le document qui leur a été distribué comporte néanmoins une partie consacrée à l’apprentissage de la programmation de la tortue (en Python), suivant ce plan :

  • Instructions (de rotation et déplacement pour la tortue)
  • Variables (application : le côté des polygones)
  • Fonctions (dessins de parties des polygones, pour éviter de faire plusieurs fois la même chose)
  • Boucles (vues entre temps dans le concours algorea)
  • Parcours d’un texte lettre par lettre

Souvent, le fait d’avoir un problème à résoudre incite les élèves à se servir des tests, boucles et définitions de fonctions de manière active : d’habitude une fois que j’ai expliqué comment fonctionnent ces subtilités, des élèves me demandent à quoi ça sert, et là c’est l’inverse : les élèves, au moment où ils ont quelque chose de répétitif à faire, me demandent comment on rédige une boucle en Python. Les notions qui sont au programme sont ainsi introduites pour répondre à des besoins.

Avant de voir comment on dessine la courbe de Sierpiński en Python, il faut déjà voir comment on programme en Python. Pour cela, programmer les déplacements d’un robot aide les élèves à s’impliquer. Et les plus rapides peuvent créer des œuvres d’art graphique.

Exemples

Dans les onglets suivants, on présente quelques œuvres d’élèves (en début de Seconde) avec les scripts Python qui les dessinent.

Rosace

Un grand classique de la tortue Python :

  1. from turtle import *
  2.  
  3. reset()
  4. for count in range(50):
  5.     forward(60)
  6.     left(64)

Télécharger

Le nombre 50 a été trouvé par tâtonnements. On obtient cette rosace où il semble qu’un trait de trop a été dessiné :

Une étude mathématique aurait permis d’optimiser le nombre de répétitions : en fait il suffisait de 45 itérations pour refermer la rosace.

Intuitif

Le script ci-dessous a été créé par tâtonnements (son exécution est d’ailleurs très longue) :

  1. from turtle import *
  2.  
  3. L = 128
  4. for count in range(1000):
  5.     forward(L)
  6.     right(L)
  7.     forward(L)
  8. L = 90
  9. for count2 in range(1000):
  10.     forward(L)
  11.     right(L)
  12.     forward(L)
  13. L = 2
  14. for count3 in range(1000):
  15.     forward(L)
  16.     right(L)
  17.     forward(L)

Télécharger

Il donne

Aquarelle

Un élève a pris le nom d’aquarelle pour ce script :

  1. from turtle import *
  2.  
  3. L = 128
  4. for count in range(48):
  5.     forward(L)
  6.     right(L)
  7.     forward(L)
  8. L = 90
  9. for count2 in range(48):
  10.     forward(L)
  11.     right(L)
  12.     forward(L)
  13. L = 2
  14. for count3 in range(200):
  15.     forward(L)
  16.     right(L)
  17.     forward(L)

Télécharger

Le résultat produit est intéressant :

Hexagones

Un script pour jouer avec des hexagones :

  1. from turtle import *
  2.  
  3. reset()
  4. L = 32
  5. pendown()
  6. for count8 in range(4):
  7.     for count in range(2):
  8.         forward(L)
  9.         left(60)
  10.     for count3 in range(4):
  11.         for count2 in range(5):
  12.             forward(L)
  13.             right(60)
  14.     for count4 in range(2):
  15.         left(120)
  16.         forward(L)
  17.         left(60)
  18.         forward(L)
  19.     for count6 in range(4):
  20.         for count5 in range(2):
  21.             forward(L)
  22.             left(60)
  23.     for count7 in range(2):
  24.         left(120)
  25.         forward(L)
  26.         left(60)
  27.         forward(L)

Télécharger

Il produit cette structure mais en passant un grand nombre de fois au même endroit :

Rosace

Ce script est mon préféré :

  1. from turtle import *
  2. reset()
  3.  
  4. for count2 in range(73):
  5.     L = 64
  6.     left(5)
  7.     for count in range(6):
  8.         forward(L)
  9.         right(60)

Télécharger

Mis à part la gestion pas optimale de la variable, l’élégance de ce script laisse difficilement prévoir le résultat :

Motifs

La figure 3 de Sierpiński est assez facile à reproduire, car la tortue n’avance (et tourne) que trois fois. Mais en essayant de reproduire les figures suivantes, on a vite tendance à chercher comment simplifier un programme Python, et cela motive

  • l’introduction des variables
  • l’utilisation des fonctions
  • les boucles

Dans les onglets suivant on présente des exemples de production d’élèves.

Variables

Voici un script Python pour la figure 4 (9 côtés) :

A priori ce script est correct (il dessine bien la figure 4 de Sierpiński), mais lorsque fut rappelée la consigne de tracer des traits de 64 pixels (et non 60), cela a représenté beaucoup de travail pour modifier certains paramètres (pas tous : l’angle lui reste de 60°) alors que si le script avait commencé par

L = 60

en utilisant ensuite cette variable L, il aurait suffi de modifier la ligne en

L = 64

Finalement, c’est parfois bien pratique, les variables !

Fonctions

Constatant que le motif de la figure 4 est formé de 3 copies de la figure 3 dont une tournée vers la gauche, une élève a rapidement eu l’idée de programmer deux fonctions et ensuite simplement les appeler :

Ici l’exercice montre tout son intérêt : il y a décomposition de la courbe de Sierpiński en trois parties et chacune de ces parties est codée dans une fonction. Le stade suivant aurait été de mettre le tout dans une nouvelle fonction puis se servir de cette fonction pour la figure 5. Mais ce premier pas vers la récursivité n’a été franchi par aucun des élèves de Seconde.

Les fonctions sont lues sur la figure originale :

Boucles

Quand on doit répéter plusieurs fois une même tâche, on utilise des boucles. Pour cela on utilise la fonction range() qui, à partir d’un entier n, crée un objet capable de boucler n fois, ou plus précisément un objet capable de faire prendre n valeurs différentes à une variable : la variable de boucle i. La syntaxe est

for i in range(n):

avec un double-point qui augmente l’indentation.

Avec ces explications, un élève a trouvé avant les fêtes de fin d’année 2021 ce script pour la figure 4 :

Indentation

En Python, les sous-structures sont représentées par l’indentation. Chaque fois qu’une ligne commence par 2×n espaces, ce qu’il se passe dans cette ligne se déroule dans une sorte de monde virtuel inaccessible aux mondes moins virtuels (ceux qui comportent moins d’espaces en début de ligne).

Cette situation rappelle un peu la sémantique de Kripke pour les mondes possibles de Leibniz (ici les mondes possibles seraient les niveaux d’indentation) :

  • Après def on entre dans un monde régi comme une forge, c’est là où on fabrique les fonctions. Les variables créées dans ce monde sont inaccessibles au monde supérieur.
  • Après for ou while on entre dans un monde provisoire où des choses seront répétées un certain nombre de fois.
  • Après if ou else on entre dans un monde hypothétique, c’est-à-dire qu’on n’y entrera peut-être pas du tout : tout dépend de la condition qui est après le if.

Après avoir abordé les rudiments de la programmation Python, il a été expliqué que for variable in n’est pas nécessairement suivi d’un range(n) mais peut très bien être suivi d’un mot (une chaîne de caractères) ce qui permet de boucler sur les lettres d’un mot. C’est d’ailleurs comme ça que les humains apprenaient à lire avant la méthode globale [3].

Figure 5

La figure 5 comportant 27 segments, il devient crucial de trouver comment faire court. Les connaissances sur les fonctions sont donc rapidement réinvesties.

Stylo

Pour ceux qui séchaient sur la partie Python, une activité préliminaire, consistant à reproduire la figure 5 au crayon, a été proposée.

L’imprimeur avait un peu insisté sur les traits de construction de Sierpiński et certains élèves ont décidé de refaire la figure entière, traits de construction compris :

D’autres ont fait preuve de soin, en repérant d’abord les sommets par lesquels passer :

Fonctions

Les fonctions gardent leur succès :

Mais comme il a déjà été dit plus haut, le passage à des fonctions qui appellent des fonctions, s’est révélé un obstacle non franchi.

Mots

Mais voici un script qui dessine lui aussi la figure 5 de Sierpiński, tout en étant bien plus court :

L’algorithme consiste à parcourir (comme on le fait en lisant, de gauche à droite) les lettres d’un mot, et

  • chaque fois que la lettre est un D, tourner à droite,
  • chaque fois que la lettre est un G, tourner à gauche.

Puis, de toute façon, avancer puisque seuls les angles changent selon l’endroit où on se trouve sur la courbe.

Toute la difficulté est de trouver le mot (succession de D et de G) de 27 lettres donnant la figure 5 de Sierpiński. Cela a été fait, en général, par parcours de la courbe sur la figure 5 de l’article.

Commentaires

Les scripts Python ont été d’abord testés puis recopiés à la main. Les commentaires (lignes en vert) ne sont pas exécutés par python et ne servent à rien. Ci-dessous ils représentent les mots donnant les autres figures de l’article de Sierpiński :

Cela permet en tout cas de voir que chaque figure comporte 3 fois plus de côtés que la figure précédente, autrement dit que chaque mot est trois fois plus long que le mot précédent.

Indentation

L’erreur d’indentation (forward au mauvais endroit) est une erreur de recopie, le programme sur l’ordinateur fonctionnait correctement :

La découverte de la méthode des mots avec la figure 5 a remotivé pratiquement tous les élèves et leur a donné l’énergie d’essayer de reproduire la figure 6 elle aussi. C’est à ce stade que l’activité prenait une allure cryptographique puisqu’il s’agissait de trouver un mot de 81 lettres sans jamais se tromper une seule fois.

figure 6

Tout d’abord, la possibilité était offerte pour les herpétophobes, de dessiner la figure au crayon sur papier pointé :

Dessins

En fait Sierpiński a tourné sa figure 6 de manière incohérente par rapport aux autres figures (peut-être une erreur de dessin, rattrapée comme il a pu). Cela a posé problème déjà pour la reproduire, ne sachant pas toujours où commencer :

Parfois le triangle extérieur a été tracé aussi pour servir de guide :

Mais parfois le tracé des 81 segments a été abandonné en cours de route pour se concentrer sur la version Python :

Lecture

Pour lire le mot, rien de tel que de regarder sur la figure 6 de Sierpiński, quitte à annoter celle-ci :

Parfois il a suffi d’annoter une partie, le reste s’en déduisant :

Ce travail est long :

mais ensuite il suffit de parcourir la courbe pour lire les lettres du mot au fur et à mesure, et là on gagne du temps.

Script

Plusieurs élèves ont réussi avant la fin de l’heure sur l’ordinateur, seuls les plus rapides ont pu recopier le script sur leur feuille. Voici un exemple :

Commentaires

Le script avec commentaires inutiles a été recopié correctement, y compris les commentaires :

Pour les plus rapides, a été posée la question : À quoi ressemblerait la figure 7 de Sierpiński s’il y en avait eu une ?. C’est l’occasion de voir si, pour la figure 6 déjà, on ne pouvait pas faire plus simple.

Syllabes

La question fondamentale est de savoir comment Sierpiński est passé

  • de D à DDD
  • de DDD à DGGDDDDGG
  • etc

afin d’appliquer la même recette au mot de 81 lettres vu pour la figure 6 et obtenir le mot de 243 lettres qui décrit l’approximation suivante de la courbe de Sierpiński. Et au passage voir si on ne pouvait pas faire plus simple pour les figures 5 et 6.

Analyse

L’idée remonte à Aristid Lindenmayer : pour passer d’un mot au mot suivant, on remplace chaque lettre de l’ancien mot par une syllabe (ici, de 3 lettres).

Au début (avant la figure 3 de Sierpiński), on a une seule lettre, mettons D puisque la tortue va vers la droite.

La figure 3 pose un problème, parce que comme Sierpiński n’orientait pas ses figures de manière stable, on ne peut pas savoir si le mot est GDD ou DDD. Pour trancher, on regarde comment passer du mot de 3 lettres (pour l’instant inconnu) au mot suivant qui fait 9 lettres :

  • la première lettre (D ou G, on ne sait pas) devient DGG
  • le D du milieu devient DDD
  • le D final devient DGG

On gagne en simplicité à considérer que le mot de la figure 3 est DDD. Mais certains D deviennent DGG et d’autres D deviennent DDD. L’alphabet de deux lettres D et G ne suffit donc pas, il faut y ajouter des minuscules :

  • la première lettre est D
  • ce D devient DDD, DDd, DdD, Ddd, dDD, dDd, ddD ou ddd. Mais lequel ?

Pour le savoir, on regarde en quoi se transforment chacune des lettres de ce mot de trois lettres. On a vu plus haut que le D du milieu se transforme en DDD (ou avec des minuscules) alors que les autres se transforment en DGG (ou avec des minuscules). Donc le seul choix convenable est que le premier D se transforme en dDd. Et le d se transforme en DGG, DGg, DgG, Dgg, dGG, dGg, dgG ou dgg.

Pour savoir lequel des 8 mots précédents est le transformé de d, on compare les figures 4 et 5 de Sierpiński : on voit que le premier G ou g se transforme en GGG (ou avec des minuscules) alors que le second G se transforme en GDD (ou avec des minuscules). Par analogie on suppose alors que le premier G est un G majuscule et se transforme en gGg et que le second G est par contre un g qui se transforme en GDD (ou avec des minuscules). Quant au D de DGg, vu qu’il se transforme en dDd, c’est qu’il est forcément en majuscule.

Bref,

  • DdDd
  • dDGg
  • GgGg
  • gGDD ou avec minuscules

À ce stade, il ne semble pas déraisonnable de supposer que la symétrie gauche-droite est respectée et donc que GGDd. L’hypothèse se vérifie soit en comparant les figures 5 et 6 de Sierpiński, soit en programmant en Python pour vérifier la concordance entre le tracé de la tortue et la fractale connue.

Fonction

Voici le résumé des règles de réécriture obtenues :

  1. {D}{dDd}
  2. {d}{DGg}
  3. {G}{gGg}
  4. {g}{GDd}

Télécharger

Ce diagramme sagittal est celui d’une application de l’alphabet de 4 lettres D, d, G et g vers l’ensemble des mots de 3 lettres formés sur cet alphabet. En Python, les applications [4] sont stockées en mémoire sous la forme de « dictionnaires » ce qui donne

  1. {'D': 'dDd', 'd': 'DGg', 'G': 'gGg', 'g': 'GDd'}

Pour peu que l’on ait donné cette valeur à une variable suffixe (parce que ces mots de 3 lettres seront des suffixes à ajouter au mot en cours de construction) :

  1. suffixe = {'D': 'dDd', 'd': 'DGg', 'G': 'gGg', 'g': 'GDd'}

alors pour avoir le transformé de la lettre lettre on écrit

  1. suffixe[lettre]

Mot

Pour obtenir le nouveau mot nm à partir de l’ancien mot mot, on

  • crée une variable nm contenant le nouveau mot, initialisé au mot vide (il n’y a rien entre les guillemets),
  • lit le mot lettre par lettre,
  • ajoute au nouveau mot nm, non pas la lettre lue, mais le suffixe (mot de 3 lettres) qui lui est associé :
  1. nm = ''
  2. for lettre in mot:
  3.       nm += suffixe[lettre]

Télécharger

Pour obtenir les figures de Sierpiński, il suffit de remplacer l’ancien mot par le nouveau, et répéter le tout.

Pour la figure 3 :

  1. mot = 'D'
  2. for _ in range(1):
  3.     nm = ''
  4.     for lettre in mot:
  5.       nm += suffixe[lettre]
  6.     mot = nm

Télécharger

Pour la figure 4 :

  1. mot = 'D'
  2. for _ in range(2):
  3.     nm = ''
  4.     for lettre in mot:
  5.       nm += suffixe[lettre]
  6.     mot = nm

Télécharger

Pour la figure 5 :

  1. mot = 'D'
  2. for _ in range(3):
  3.     nm = ''
  4.     for lettre in mot:
  5.       nm += suffixe[lettre]
  6.     mot = nm

Télécharger

et pour la figure 6 :

  1. mot = 'D'
  2. for _ in range(4):
  3.     nm = ''
  4.     for lettre in mot:
  5.       nm += suffixe[lettre]
  6.     mot = nm

Télécharger

Dessin

Pour passer du mot au dessin, on fait comme plus haut, à ceci près que la tortue ne tourne pas à droite uniquement lorsque la lettre est un D mais lorsque c’est une lettre du mot Dd :

  1. from turtle import *
  2.  
  3.  
  4. def sierpinski(mot):
  5.     for lettre in mot:
  6.         if lettre in 'Dd':
  7.             right(60)
  8.         else:
  9.             left(60)
  10.         forward(L)

Télécharger

Sur le site Numworks on peut tester le script ci-dessous :

En bouclant 6 fois on reconnaît bien la courbe de Sierpiński :

Il est intéressant de comparer cette approche avec celle-ci : les règles de réécriture sont équivalentes mais ne se ressemblent pas.

Et si on ne tournait que de 45° ?

Le même mot, mais avec des rotations de 45° au lieu de 60°, donne cette courbe qui semble bien différente de celle de Sierpiński :

Courbe jordanienne

La raison pour laquelle Sierpiński a ajouté à sa construction classique (enlever des triangles des milieux), celle de ces courbes, c’est qu’il voulait montrer par cette construction que sa courbe est jordanienne, c’est-à-dire qu’elle sépare le plan en deux parties que l’on peut appeler « au-dessus » et « au-dessous » de la courbe. En coloriant en vert la partie « au-dessous » de la courbe, on obtient ce dessin :

La fractale obtenue à la limite infinie a pour aire une fraction $x$ de l’aire totale du triangle. En effet on constate que parmi les 4 triangles initiaux,

  • celui du centre est entièrement colorié : aire $\frac{1}{4}$,
  • celui du haut est une version réduite du tout : aire $\frac{x}{4}$
  • celui en bas à gauche est le négatif d’une version réduite du tout : aire $\frac{1-x}{4}$,
  • celui en bas à droite est également le négatif d’une version réduite du tout : aire $\frac{1-x}{4}$ aussi.

Donc $x=\frac{1}{4}+\frac{x}{4}+\frac{1-x}{4}+\frac{1-x}{4}=\frac{1+x+2-2x}{4}=\frac{3-x}{4}$ d’où $4x=3-x$ dont la solution $\frac{3}{5}$ est bien une fraction : 60 pourcent de l’aire du grand triangle est coloriée.