Construire l'éponge de Menger par script avec CaRMetal

Dans cet article, on va voir comment programmer simplement la construction de l'éponge de Menger.

eponge 01figure réalisée avec CaRMetal


Menger 01
Menger 02

Par Niabot — Travail personnel, CC BY 3.0, https://commons.wikimedia.org/w/index.php?curid=7780910

 L'éponde de Menger est un solide fractal. On peut décrire sa construction ainsi :
A chaque étape, on "coupe" le cube en frites, puis en dés (27 dés). On ne garde que les dés sur les arêtes, et on recommence sur les dés restants(27-7=20 dés).

1) On lance CaRMetal et on crée une nouvelle figure 3D.

nfig3D

On dispose alors d'un repère 3D \($(O,\vec{OX},\vec{OY},\vec{OZ})\) qui permet de travailler en 3D.

repere

Par ailleurs, une nouvelle palette 3D est apparue dans le dock de droite.
Cette palette ne va pas nous servir beaucoup ici car on va tout faire par script. Mais elle permet de régler les préférences par défaut pour les polygones (les faces des cubes), à savoir :
* un contour normal
* un remplissage
* pas de transparence

2) La palette 3D (tout comme la palette Construction) est couplée à la palette Aspect&couleur.

On sélectionne successivement :
* Polygone dans la palette 3D
* contour normal dans la palette Aspect&couleur
* rempli dans la palette Aspect&couleur
* opaque dans la palette Aspect&couleur

prefs

Remarque : on pourrait aussi le faire par script sans modifier les préférences de façon pérenne en écrivant les instructions suivantes dans le script :

ClicVirtuel("polygone",vrai)
ClicVirtuel("épaisseur0",vrai)
ClicVirtuel("rempli",vrai)
ClicVirtuel("opaque",vrai)

3) On crée un nouveau script, que l'on appelle eponge-Menger :

nscript

4) On active l'option en français (case à cocher) et on commence le script par pseudo-code pour activer le mode pseudo-code.

pseudo frb

L'assistant va générer des instructions en français et en pseudo-code.
Le script sera interprété comme étant du pseudo-code.

5) On commence par créer une procédure(fonction) cube pour construire les six faces d'un cube centré en x,y,z et de demi-arête c.

fCube

On a utilisé un nommage méthodique des points pour faciliter la lecture :
P-directionX-directionY-directionZ avec 0 pour le sens négatif et 1 pour le sens positif

Ligne 11 à 18 : on masque les points.

Ligne 19 à 24 : on crée les faces avec la CaRCommande Quadrilatère3D, qui crée le polygone et le place sur un calque dont le numéro correspond à sa profondeur (celle de son barycentre) par rapport au plan frontal (ce qui permettra de gérer la superposition et le masquage des faces).

Ligne 25 à 30 : On colorie avec un même couleur les faces orientées dans le même sens. Ces couleurs sont choisies méthodiquement en utilisant les trois composantes RVB (Rouge, Vert et Bleu).

6) On crée une procédure récursive.

recursion

On utilise le fait que la récursion s'applique seulement aux cubes sur les arêtes pour présenter un script plus clair.
abs(i)+abs(j)+abs(k)  est égal à 0 pour le centre, et à 1 pour les centres des faces.
La demi-arête est divisée par 3 lors de la récursion.
Les centres des nouveaux petits cubes sont décalés de \(\dfrac{2}{3}\) de la demi-arête.

Voici le script complet :

pseudo-code
fonction cube(x,y,z,c)
    P111 ⟵ Point3D(x+c,y+c,z+c)
    P011 ⟵ Point3D(x-c,y+c,z+c)
    P101 ⟵ Point3D(x+c,y-c,z+c)
    P110 ⟵ Point3D(x+c,y+c,z-c)
    P001 ⟵ Point3D(x-c,y-c,z+c)
    P100 ⟵ Point3D(x+c,y-c,z-c)
    P010 ⟵ Point3D(x-c,y+c,z-c)
    P000 ⟵ Point3D(x-c,y-c,z-c)
    Cacher(P111)
    Cacher(P011)
    Cacher(P101)
    Cacher(P110)
    Cacher(P001)
    Cacher(P100)
    Cacher(P010)
    Cacher(P000)
    faceD ⟵ Quadrilatère3D(P111,P011,P010,P110)
    faceG ⟵ Quadrilatère3D(P101,P001,P000,P100)
    faceH ⟵ Quadrilatère3D(P111,P011,P001,P101)
    faceB ⟵ Quadrilatère3D(P110,P010,P000,P100)
    faceAv ⟵ Quadrilatère3D(P111,P101,P100,P110)
    faceAr ⟵ Quadrilatère3D(P011,P001,P000,P010)
    MettreCouleurRVB(faceD,0,200,0)
    MettreCouleurRVB(faceG,0,100,0)
    MettreCouleurRVB(faceH,0,0,200)
    MettreCouleurRVB(faceB,0,0,100)
    MettreCouleurRVB(faceAv,200,0,0)
    MettreCouleurRVB(faceAr,100,0,0)

fonction menger(x,y,z,c,n)
   si n≤0
      cube(x,y,z,c)
   sinon
      pour var i allant de -1 à 1
          pour var j allant de -1 à 1
             pour var k allant de -1 à 1
                si abs(i)+abs(j)+abs(k)>1
                   menger(x+i×c×2/3,y+j×c×2/3,z+k×c×2/3,c/3,n-1)

menger(0,0,0,1,2)

7) On lance le script.

go

(en accéléré pour la fin de la construction)

Remarque : il y a très peu de liens dynamiques dans cette figure. Une version plus ("réellement") dynamique est  présentée dans cet article (pour montrer la différence).

Pièces jointes :

eponge-Menger.zir [figure CaRMetal]