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.

La 3D dans CaRMetal 4.0
Article mis en ligne le 11 décembre 2015
dernière modification le 17 avril 2021

par Alain Busser, Patrice Debrabant

La version 4.0 de CaRMetal est marquée par une avancée de son module 3D et par l’apparition des nouveaux outils qui l’accompagnent.
Un des objectifs était de reconquérir de l’engagement direct dans les manipulations relatives à un espace 3D imaginé et par nature inaccessible.
C’était une gageure. On verra dans quelle mesure on y est parvenu.

Plus prosaïquement, cet article présente les nouveautés de CaRMetal 4.0 en s’attachant à la pratique du logiciel.

Cet article peut être librement diffusé et son contenu réutilisé pour une utilisation non commerciale (contacter l’auteur pour une utilisation commerciale) suivant la licence CC-by-nc-sa (http://creativecommons.org/licenses/by-nc-sa/3.0/fr/legalcode)

pavage 3D
Pavage de l’espace par des octaèdres et des tétraèdres réguliers (réalisé avec CaRMetal 4.0)

Préface

CaRMetal est un logiciel de géométrie dynamique qui se distingue, dès l’origine de sa création par Eric Hakenholz, par l’effort portée sur la manipulation directe.
Comme il le rappelle lui-même dans cet article, les quatre principes pour définir la notion de manipulation directe sont :

  • la présentation permanente des objets d’intérêt ;
  • l’utilisation d’actions physiques au lieu de commandes textuelles : "voir et montrer au lieu de se rappeler et taper” ;
  • le résultat des actions physiques doit être immédiatement visible ;
  • ces actions doivent être rapides, incrémentales et réversibles.

L’application de ces principes (ou plus simplement leur assimilation car cela reste très intuitif) induit le développement dès que c’est possible, et à tous les niveaux du logiciel, de mécanismes alternatifs plus en manipulation directe.
Une manifestation de cette approche consiste, dès qu’il est possible d’en faire l’économie, à bannir les boîtes de dialogue, qui sont bloquantes et éreintent la manipulation directe.

Depuis la version 2.4, il est possible de faire de la 3D (plus exactement de la pseudo-3D) dans CaRMetal. Mais jusqu’à la version 3.8.7, la gestion des points 3D se faisait de façon indirecte, par l’intermédiaire d’expressions.
En développant le passage de la version 3.8.7 à la 4.0, on s’est efforcé de créer une nouvelle approche de la 3D mieux intégrée au logiciel, et de recréer de la manipulation directe, en particulier pour les points 3D.
C’est ce que l’on propose de présenter ici à travers un tour d’horizon des nouveautés de CaRMetal 4.0.

Remarque : l’article entre directement dans le vif du sujet en présentant la correction en vidéo de deux exercices de géométrie 3D donnés au BAC S session juin 2015 (Métropole et Amérique du Nord).


Plan de l’article :

Introduction : Exercices pratiques pour se mettre dans le bain :
Correction de deux exercices de géométrie 3D donnés au BAC S session 2015

I) La 3D

  • A) Etat des lieux de la version 3.8.7
  • B) Nouvelle approche de la version 4.0
    1. L’outil point 3D
    2. La CaRCommande Point3D
    3. Le déplacement des points 3D
    4. Les scripts de vue
    5. La gestion des plans
  • C) Tour d’horizon de CaRMetal 4.0
    1. La palette 3D
    2. Outils invisibles
    3. Assistant de script et CaRCommandes 3D
    4. Dossier 3D de macros de menu

II) Nouveautés non liées à la 3D

  • A) Enrichissement du Javascript disponible pour les scripts
  • B) Le BEGINNER mode
  • C) Correction de bugs

Introduction : Correction en vidéo de deux exercices du BAC S (session 2015)

Amérique du Nord, juin 2015, exercice 1 (extrait du site de l’APMEP)


Métropole - la Réunion, juin 2015, exercice 2


I) La 3D

A) Etat des lieux de la version 3.8.7

Pour commencer, précisons que CaRMetal n’est pas un logiciel de 3D, mais un logiciel de pseudo-3D. Quand on crée une nouvelle figure 3D, on créée en fait une nouvelle figure 2D dans laquelle un trièdre mobile (par clic droit) OXYZ est créé automatiquement (ce trièdre est représenté en perspective cavalière sur notre figure 2D, c’est cela que l’on voit).
Et la présence de ce trièdre suffit à faire de la 3D en perspective cavalière.

Comment cela est-il possible ?
En fait, c’est assez simple : en utilisant les formules de projection.

Imaginons l’espace 3D associé au trièdre dont on visualise actuellement la projection dans notre figure 2D.
Imaginons un point A(2,3,4) de cet espace 3D. Comment verra-t-on ce point dans notre figure 2D, autrement dit quelle sera sa projection ?

OA = 2OX+ 3OY+ 4OZ

x(A) = x(O)+ x(OA) = x(O)+ 2*(x(X)-x(O))+ 3*(x(Y)-x(O)) + 4*(x(Z)-x(O))
y(A) = y(O)+ y(OA) = y(O)+ 2*(y(X)-y(O))+ 3*(y(Y)-y(O)) + 4*(y(Z)-y(O))

Manipulation proposée :
Ouvrir CaRMetal. Créer une nouvelle figure 3D. Créer un point 2D.
Clic droit pour faire afficher ses coordonnées.
Puis copier-coller les formules ci-dessus dans les coordonnées. Un seul copier-coller devrait suffire, le système de « recopie automatique » (activé par défaut mais qui peut être désactivé = c’est un bouton interrupteur) extrapole logiquement en y.

On obtient un point A qui se comporte comme un point 3D.

On retrouve cette formule dans les scripts quand on utilise le bouton point 3D de l’assistant de script :

La CaRCommande générée est une CaRCommande Point. On retrouve les formules précédentes dans les coordonnées du point généré.

En pratique, l’usage dans CaRMetal 3.8.7 était d’utiliser une fonction Javascript personnalisée plutôt que cette syntaxe.
Il y avait différentes options, plus ou moins compliquées, pour implémenter cette fonction.
Une des premières, et des plus simples, était la suivante :

  1. function TracerPoint3D(nom, ux, uy, uz) {
  2. vx=ux ; vy=uy ; vz=uz ;
  3. up=Point(nom,
  4. "x(O)+_vx*(x(X)-x(O))+_vy*(x(Y)-x(O))+_vz*(x(Z)-x(O))",
  5. "y(O)+_vx*(y(X)-y(O))+_vy*(y(Y)-y(O))+_vz*(y(Z)-y(O))") ;
  6. }

Télécharger

Le dédoublement des paramètres dans la fonction est utilisé pour affecter les paramètres à des variables globales, ces variables globales pouvant ensuites être « parsées » via la syntaxe _ (les variables sont remplacées par leur valeur dans la chaîne de caractères).

Ce dédoublement des paramètres peut être évité en décomposant la chaîne de caractères, ce qui donnerait pour l’abscisse x :

  1. "x(O)+" + ux + "*(x(X)-x(O))+" + uy + "*(x(Y)-x(O))+" + uz + "*(x(Z)-x(O))"

C’est la même chose, mais moins lisible.

Dans l’interface de construction, le bouton était le suivant :

On obtenait finalement ceci :

Autrement dit, on obtenait trois expressions affichées sur la figure (car il fallait bien pouvoir y accéder pour les modifier), ces trois expressions étant ancrées à un point 2D mobile (ici A) par commodité.
Les trois expressions permettaient de piloter un point 3D (pas représenté ici).

C’était perfectible, bien que fonctionnel, et c’est ce que l’on a cherché à modifier.

B) Nouvelle approche dans la version 4.0

A ce stade de l’article, je vous propose, si ce n’est pas déjà fait, de télécharger et d’installer CaRMetal 4.0. en suivant ce lien vers la page de téléchargement.

Remarque : il s’agit encore (à l’heure où nous écrivons) d’une version bêta car elle comporte des petits défauts à corriger. Mais pas de souci.

1) L’outil point 3D

Pour créer des points 3D, il faut d’abord créer une nouvelle figure 3D, ce qui fera apparaître un repère OXYZ (orthonormé direct) et la possibilité de rendre visibles ce repère et le sol. Il est alors toujours possible de créer des points 2D dans ce repère, mais on ne sait pas trop à quoi ça peut servir [1].... Alors la palette d’outils habituelle est fermée par défaut et une palette spéciale pour la 3D apparaît. Le premier outil ressemble à ceci :

Pour créer un point 3D, il suffit alors, après avoir sélectionné cet outil, de cliquer sur la figure, là où on veut placer le point.
On crée bien un point 3D, comme on peut le vérifier en faisant tourner le repère (clic droit).

  • Mais m’sieur, c’est où, « là où je veux placer le point » ?
  • Ben là !
  • Oui mais là c’est devant l’écran ou derrière l’écran ?
  • Entre les deux.
  • Mais où ça, précisément ?
  • Où il y a le centre du repère (le point O).

Diantre ! Pour voir ce que ça donne, pourquoi ne pas cliquer plusieurs fois sur l’écran pour créer un nuage de points ?

On vient de créer une oeuvre pointilliste mais c’est pas non plus bouleversant d’intérêt.
Faisons un effort et tournons la figure. Fiat lux, quelle belle voiture : on voit bien que tous ces points sont coplanaires.

Pour les connaisseurs de géométrie dans l’espace, on peut faire quelque chose de plus précis, avant de tourner la figure : Créer 3 points dans le plan de l’écran, matérialiser deux vecteurs avec ces trois points, puis construire le produit vectoriel des deux vecteurs qu’ils forment (avec la macro produit vectoriel du dossier 3D) : On voit que ce produit vectoriel « n’émerge pas » (à moins de tourner le repère), car il est perpendiculaire à l’écran.

En fait, l’objectif était de créer un outil point 3D qui fonctionne de façon analogue à l’outil point 2D.

Tout d’abord, les coordonnées 3D d’un point 3D devaient prendre place dans la barre de propriété des points (et remplacer les coordonnées 2D).

Ensuite, il fallait que l’outil Point 3D fonctionne selon le paradigme de CaRMetal : création du point 3D au clic, puis ajustement éventuel dans la barre de propriétés.
Pour que la mécanique fonctionne, il faut que le point 3D créé au clic soit tel que sa projection sur l’espace 2D de la figure coïncide avec la position du clic.
Le point 3D créé doit donc nécessairement être situé sur la droite perpendiculaire au plan frontal passant par la position du clic. Et il faut faire un choix.

Le choix est d’épingler le point dans le plan frontal passant par O [2]. Ce choix permet un retour visuel immédiat (engagement direct) sur la création des points créés.

Notons (si l’on en doutait) que la perpendiculaire au plan frontal passant par le clic étant entièrement visible, son intersection avec un plan (ou avec n’importe quoi) est aussi visible.

2) La CaRCommande Point3D

On a désormais une syntaxe simplifiée avec 3 paramètres (+1 facultattif pour le nom du point, dans ce cas, à placer au début) qui fonctionne comme la CaRCommande Point.

Exemple d’utilisation : Construction d’un cube plein

Le script suivant dessine un nuage de points remplissant aléatoirement le cube unité (dont O, X, Y et Z sont des sommets) :

  1. for (i=0; i<400; i++){
  2.         p = Point3D("P"+i,Math.random(),Math.random(),Math.random());
  3.         SetPointType(p,"point");
  4.         SetThickness(p,"thick");
  5.        
  6. }

Télécharger

Pour voir d’autres exemples, la version webGL...

3) Le déplacement des points 3D

Là encore, l’objectif est d’obtenir un comportement analogue à celui des points 2D : un point 3D peut être libre, auquel cas on peut le déplacer à la souris.
Mais on dispose d’une souris 2D pour se déplacer dans un espace 3D. Comment faire ?

On a fait en sorte que le point se déplace sur son plan frontal : la position du trièdre détermine une direction face à nous, et on se déplace sur un plan orthogonal à cette direction. Ce mode de déplacement est contextuel. Et aucune direction n’est privilégiée.
De plus, ce mode de déplacement est cohérent avec le positionnement du point 3D dans le plan frontal passant par O (le point peut être positionné puis déplacé en restant dans le plan contextuel sur lequel on épingle les points).

On peut noter que ce n’est pas le même mode de déplacement que dans GeoGebra 3D qui impose des déplacements moins souples, soit dans un plan horizontal z3D=lambda, soit le long d’un axe vertical (et utilise en outre un clic interrupteur) [3]

Je vous conseille d’essayer par vous-même pour vous familiariser avec ce mode déplacement :
Placer 4 points 3D en utilisant l’outil point 3D, puis modeler un tétraèdre. C’est un peu comme façonner une pièce au tour de potier (précisons toutefois que ce « tour de potier » a un axe qui se balade, vous ne le trouverez pas dans le commerce en vente libre.).

4) Les scripts de vue

Ces scripts (vue d’avion, vue de face, vue de droite, retour en vue mobile) permettent de déplacer le trièdre, et peuvent être utilisés avant de créer un point 3D pour le positionner sur un plan précis.

Ces scripts sont accessibles, et simples à comprendre. Ils peuvent être modifiés si nécessaire (en particulier pour modifier la vitesse).
Voici par exemple le détail du script vue d’avion (aerial view) :

En remplaçant 50 par 10, on obtiendra un script 5 fois plus rapide.

5) La gestion des plans

Pas question de représenter entièrement un plan, la figure deviendrait illisible. Un plan sera systématiquement représenté par un polygone (en pratique un triangle ou un carré). On verra plus loin le cas de la macro plan médiateur, qui créé un carré ou un triangle dilatable qui permet d’affiner la représentation.

Un certain nombre d’outils 3D (en fait, il s’agit de macros), dans la palette 3D ou dans les macros de menu du dossier 3D prennent pour paramètre un plan.
Pour désigner ce plan, on a fait le choix de le désigner systématiquement par trois de ses points. Cela permet de désigner le plan directement sur la figure sans passer par la fenêtre algèbre, et quelle que soit la superposition des plans (polygones) de la figure, les points restant toujours sélectionnables (car les points sont « transperçant »).
Un plan pourra aussi être désigné sans être tracé, ce qui peut être utile.

Par exemple, pour utiliser l’outil projection orthogonale sur un plan de la palette 3D, on désignera trois points du plan puis le point à projeter (comme indiqué dans la ligne d’invite en bas de la fenêtre).
(L’icone de l’outil renseigne aussi sur son fonctionnement.)

Exemple d’utilisation

Définition : On appelle hauteur d’une pyramide, le segment joignant son sommet au projeté orthogonal de celui-ci sur la base.

Pour construire la hauteur d’une pyramide, on peut donc appliquer l’algorithme suivant :

  • On projette orthogonalement le sommet sur la base (en choisissant trois quelconques des sommets de la base) ; résultat en marron ci-dessous ;
  • On joint le point ainsi obtenu au sommet à l’aide de l’outil « segment 3D » ; résultat en rouge :

Cet outil sert donc à construire des hauteurs. L’élève près du radiateur de demander à quoi sert de construire une hauteur.
ça sert à prendre de la hauteur.

  • M’sieur, dans la formule « base fois hauteur sur 3 », la hauteur est un nombre ?
  • Oui, évidemment. Seuls les nombres peuvent être multipliés (à jeun).
  • Alors pourquoi vous dites que la hauteur est un segment ?
  • Par abus de langage, on désigne par le même mot « hauteur », le segment, sa longueur et même la droite.
  • M’sieur, on a le droit de faire des abus de langage ? Ma mère, elle dit que non.
Amis de la psychologie, bonsoir!

Dans ce petit aparté, que l'on peut passer allègrement, on va s'aventurer (car c'est de l'interprétation «sauvage»...) à expliquer ce qui constitue un petit verrou psychologique à l'adoption de l'approche de CaRMetal pour construire certains objets.

Prenons le cas simple de la création d'un cercle de rayon 2.
Une approche répandue consiste à passer par une boîte de dialogue : on sélectionne l'outil, on sélectionne le centre, une boîte de dialogue apparaît en pop up. On entre alors le rayon (exact), et on obtient le cercle.
Dans CaRMetal, on crée directement le cercle, ou plus exactement une version approchée de ce cercle en manipulation directe (en pratique, on clique un peu où l'on veut pour donner vie au cercle). La barre de propriété du cercle s'active. On ajuste le rayon.

Ce dernier paradigme semble objectivement plus adapté à la géométrie dynamique. Mais il ne va pas sans soulever une espèce de petite résistance mentale, qui contrarie souvent ceux qui débutent avec CaRMetal et qui se retrouvent bloqués car ils ne savent pas construire ce cercle de rayon donné (personnellement, je suis passé par cette phase un peu déroutante).

Pourquoi cette résistance ?
On peut considérer que ce paradigme n’est pas «naturel» car nous sommes conditionnés par notre expérience du monde réel (et de la géométrie avec les instrument traditionnels) à rechercher d’emblée la construction exacte et parfaite de l'objet. L'ajustement est «douloureux» (et sanctionné par des mécanismes psychiques) car dans le monde réel il est le signe que l'on a commis une erreur ou une imprécision. Le brouillon est pénalisant, car il laisse une trace (et surtout une trace mentale).

Cette résistance est naturelle, mais il me semble utile d'en prendre conscience pour la corriger. Car dans le contexte d'un logiciel de géométrie dynamique, la donne change radicalement : l'erreur ou l'imprécision (si bien-sûr elle est corrigée...) n'est aucunement pénalisante et ne laisse pas de trace. Elle ne coûte rien.
(Il n'en va pas de même dans la vie de tous les jours. Hélas, mille fois hélas...)

Le processus de création d'un cercle de rayon 2 par manipulation directement est un processus naturel, mais dont le naturel doit être conquis et peut demander un petit temps d'adaptation. Voici juste ce que l'on souhaitait souligner ici.
(Et on retrouve ce même processus à plusieurs reprises, en particulier lors de la création d'un point 3D).

C) Tour d’horizon de CaRMetal 4.0

1)La palette 3D

  • Outil intersection 3D de lignes :
    Par ligne, on entend ici une droite ou un cercle 3D.
    L’intersection peut aussi être créée directement avec l’outil point 3D (comme en 2D).

On a vu plus haut que la hauteur d’une pyramide est définie à partir de son sommet et de sa base. Mais la base d’un tétraèdre est un triangle, comme ses faces latérales, et un tétraèdre a donc 4 bases, et du coup, 4 hauteurs. En voici deux (les bases correspondantes sont coloriées) :

(au passage on remarque comment CaRMetal représente les angles dans l’espace)

Bien, il semble clair que ces hauteurs se croisent, alors pourquoi pas construire leur intersection histoire de voir si par hasard elle ne serait pas aussi sur les deux autres hauteurs (on ne sait jamais, certains théorèmes du plan pourraient rester vrais dans l’espace...) ? Et bien, CaRMetal refuse de construire l’intersection !

  • M’sieur il est tout buggué vot’logiciel !
  • Ah bon pourquoi ?
  • Ben j’arrive pas à le construire ce point d’intersection !
  • Et ça veut forcément dire que le logiciel est bugué ?
  • Ben oui, puisque l’outil d’intersection ne marche pas !
  • Quelle intersection au fait ?
  • Celle entre ces deux droites.
  • Est-ce qu’elles sont sécantes au moins ces deux droites ?
  • Ben oui ça se voit.
  • Pas certain, tourne un peu le tétraèdre pour voir :
  • ah tiens, non, elles ne sont pas sécantes finalement.
  • Finalement ce n’est pas le logiciel qui est buggué, mais la perception de l’espace induite par la projection plane.
  • Si vous le dites...
  • En fait les droites ne sont pas coplanaires et dans ce cas elles n’ont pas d’intersection.

Pour aller plus loin, les droites non sécantes, comme en géométrie hyperbolique, ont une perpendiculaire commune, qu’une macro permet de construire, ainsi que les points d’intersection de cette perpendiculaire commune avec les deux hauteurs :

La notion de perpendiculaire commune était présente dans le sujet de bac S 2015 (exercice 2).

Autre chose : Est-il possible que deux hauteurs d’un tétraèdre soient quand-même sécantes ? Dans ce cas est-il possible que d’autres hauteurs soient sécantes aussi, et à quoi peut ressembler un tel tétraèdre ? Là on arrive au sujet du bac S 2005 La Réunion, et la réponse est surprenante : Un tétraèdre est orthocentrique si et seulement si ses arêtes (opposées) sont perpendiculaires deux à deux. L’adjectif « orthocentrique » signifie évidemment que ses 4 hauteurs sont concourantes en un point qui est l’orthocentre du tétraèdre. CaRMetal est muni d’une macro permettant, à partir de 3 points, de construire un tétraèdre orthocentrique, dont le 4e sommet est mobile sur une droite déterminée par les autres sommets.

Ce résultat est d’autant plus surprenant qu’un tétraèdre quelconque possède

  • un centre de gravité (milieu du segment joignant les milieux de deux arêtes opposées) ;
  • une sphère circonscrite et son centre (constructibles par une macro) ;
  • une sphère inscrite et son centre (également constructibles par une macro)

Voici par exemple un tétraèdre (vert), inscrit dans la sphère bleue et circonscrit à la sphère rouge :

  • Outil point sur polygone (mise à jour de l’outil) :
    L’outil étant sélectionné, on peut épingler un point sur un polygone (qui jouera souvent le rôle d’un plan).
    Il s’agit d’un point sur objet. On verra au B) les points sur un objet de type ligne, créés directement avec l’outil point 3D.
    On notera qu’il y a un bug de l’invite...
  • Outil arête 3D :
    Cet outil permet de créer une arête 3D en gérant les arêtes cachée (en pointillés). C’est cet outil qui a été utilisé pour créer les solides de Platon.
  • Outil milieu 3D :
    Outil milieu qui crée des points 3D à la volée.

Exemple d’utilisation dans le tétraèdre : Un tétraèdre, ça a 6 arêtes donc 6 milieux. Si on élimine deux arêtes opposées (en marron ci-dessous) on ne garde que 4 milieux :

Bizarre, on dirait que ces 4 points sont coplanaires, non ?

En fait non seulement ils forment un quadrilatère (ils sont coplanaires), mais en plus ce quadrilatère est un parallélogramme : C’est le théorème de Varignon dans l’espace. Ce résultat est intéressant parce que d’une part la démonstration du théorème de Varignon (dans le plan) ne fait appel qu’à des outils vus au collège (transitivité du parallélisme et de l’égalité, droite des milieux) et qu’une fois vue cette démonstration il suffit de poser la question « à quel moment exactement a-t-on utilisé le fait que les 4 points du départ sont coplanaires ? ».

  • Outils transformations 3D :
    Projection orthogonale, symétrie centrale, symétrie par rapport à un plan, translation.
  • Outils objets 3D :
    Vecteur, droite, demi-droite, segment, polygone
    Idem qu’en 2D, mais crée des points 3D à la volée.
  • Outil sphère de rayon donné :
    On désigne le centre de la sphère, qui est créée instantanément avec un rayon 1, que l’on peut ensuite ajuster dans la barre de propriétés (= inspecteur d’objet).

La sphère est créée dès le clic désignant le centre. On notera que ce n’est pas le même processus qu’en 2D, et cela nous ramène à notre aparte psychologique :
Cette option serait possible aussi en 2D, elle éviterait le blocage que rencontrent parfois les débutants, mais elle ferait perdre de l’engagement direct.

En fait, on peut plutôt se demander pourquoi on n’a pas fait pareil en 3D qu’en 2D. Le problème vient du fait que le clic qui donnerait vie à la sphère pourrait se faire sur un point 3D existant qui, à moins d’être dans le plan frontal, ne serait pas sur la sphère. Le retour visuel pourrait être déroutant, c’est pourquoi on a fait ça différemment. Pour l’instant.

En guise d’application, on va construire ce nuage de sphères (c’est une figure 3D) :

Ce nuage est construit par récursivité en utilisant une macro. On va donc en profiter pour parler de macro en 3D.

Mais avant cela, disons un mot du rapport existant entre l’outil 3D « sphère de rayon donné » et l’outil 2D « cercle de rayon donné » (qui peut être utilisé dans un espace 3D).
La projection de la sphère de rayon donné est le disque de même rayon. Par conséquent, si on construit un disque de rayon donné centré en un point 3D (ce qui est possible), on obtient visuellement une sphère (dont l’équateur n’est pas représenté).
L’intérêt de cette méthode alternative pour construire une sphère de rayon donné réside dans le fait que la construction de l’équateur (représenté par une ellipse) mobilise beaucoup de ressources du logiciel.
Et comme ici on souhaite construire beaucoup de sphères, c’est cette méthode que l’on va utiliser.

La macro prend pour paramètres une sphère (= un disque centré en un point 3D) et une expression (en pratique un curseur).
Elle construit six sphères dans les six directions cardinales de l’espace, à une distance égale à 1.

On commence par construire la sphère bleue et un curseur nommé param. (Pour le curseur, on a choisi le deuxième outil dans la palette Contrôles, on pourrait aussi transformer une expression en curseur.)
Les sphères construites (en rouge) ont un rayon égal à R*param , où R est le rayon de la sphère initiale et param la valeur du curseur du même nom. Ce qui donne dans la barre de propriété d’une sphère bleue :

Rappelons comment on construit la macro en 3D :

Tous les objets 3D dépendant de O, X, Y et Z, on doit les désigner dans la macro.

    • Menu Macros/Créer une nouvelle macro.
    • Comme objets initiaux, désigner successivement :
      O, X, Y, Z, c1 (= la sphère bleue), param (= l’expression ou le curseur).
    • Comme objets finaux, désigner successivement les six sphères bleues.
    • Nommer la macro (par exemple flocon)

Si on veut pouvoir utiliser cette macro commodément, on fixe les initiaux O, X, Y et Z.

    • Montrer le panneau de gauche (à côté du petit singe).
    • Clic droit sur la macro, puis Montrer les propriétés

    • Fixer O, X, Y et Z (cases à cocher).

On dispose alors d’une macro fonctionnelle.

Et on passe au script :

  1. function nuage(n,c) {
  2.         if (n>0) {
  3.                 var t=ExecuteMacro("flocon","O,X,Y,Z,"+c+",param");
  4.                 for var i from 0 to 5 {
  5.                         nuage(n-1,t[i]);
  6.                         SetRGBColor(t[i],Math.ceil(Math.random()*255),+Math.ceil(Math.random()*255),Math.ceil(Math.random()*255));
  7.                 }
  8.         }
  9. }
  10. nuage(3,"c1");

Télécharger

Remarques :

    • L’aspect des sphères doit être fixé avant de lancer la macro.
    • Dans ExecuteMacro, on doit mettre les initiaux (pourtant fixés).
    • La couleur des sphères est choisie aléatoirement.
    • On a utilisé une boucle for simplifiée générée automatiquement par l’assistant en mode débutant (voir plus loin) (mais le var, important ici, a été ajouté à la main).

Pour plus d’information sur la récursivité dans CaRMetal, on pourra se reporter à cet article.

Flocon
Figure CaRMetal avec script (lancer le script scriptFlocon).
  • Outil sphère passant par un point
  • Outil cercle 3D d’axe donné passant par un point :
    On désigne l’axe (droite 3D), puis le point.
  • Outil cercle 3D axe/direction, centre, rayon :
    On désigne l’axe/direction (droite 3D), puis le centre, et enfin une expression donnant le rayon. Cette expression peut être un curseur.
  • Outil cercle 3D passant par 3 points
  • Outil angle 3D  :
    Affichage 3D des angles.
  • Intersections de surfaces :
    plan/droite, plan/plan, sphère/droite, sphère/plan, sphère/sphère

On notera que l’ordre d’entrée des paramètres est donné dans l’invite.

Ces outils permettent de représenter des sections dans l’esprit du programme du collège.

Dans certains cas, comme celui de la section du cube par un plan, il est plus facile de représenter la section dans des configurations particulières. Avec le risque d’oublier les autres...

On propose ici, à titre expérimental, de construire par script un outil permettant de représenter dynamiquement la section d’un cube par n’importe quel plan.
En pratique, le plan sera représenté par un parallélogramme que l’on va grillager par des petits parallélogrammes. Chaque petit parallélogramme aura un affichage conditionnel : il sera masqué si son centre n’est pas à l’intérieur du cube.

On créé le cube avec l’outil idoine. On place trois point libres A, B, C. Puis on complète le paralélogramme CABD par translation.
On construit les vecteurs $v1=\overrightarrow{AB}$ et $v2=\overrightarrow{AC}$ (vecteurs masqués).

Puis on construit un tableau un double-entrée contenant tous les points du maillage. Ces points sont masqués.
On construit alors tous les petits parallélogrammes, et on leur affecte un affichage conditionnel.

  1. nbPoints=50;
  2.  
  3. A=[];
  4. for i from 0 to nbPoints {
  5.         A[i]=[];
  6.         for j from 0 to nbPoints {
  7.            A[i][j]=Point3D("x3D(A)+"+i/nbPoints+"*x3D(v1)+"+j/nbPoints+"*x3D(v2)",
  8. "y3D(A)+"+i/nbPoints+"*y3D(v1)+"+j/nbPoints+"*y3D(v2)",
  9. "z3D(A)+"+i/nbPoints+"*z3D(v1)+"+j/nbPoints+"*z3D(v2)");
  10.                 Hide(A[i][j]);
  11.         }
  12. }
  13.  
  14. C=[];
  15. for i from 0 to nbPoints-1 {
  16.         C[i]=[];
  17.         for j from 0 to nbPoints-1 {
  18.                 C[i][j]=Polygon(A[i][j]+","+A[i+1][j]+","+A[i+1][j+1]+","+A[i][j+1]+","+A[i][j]);
  19.                 SetColor(C[i][j],"blue");
  20.                 Conditional(C[i][j],"hidden","x3D("+A[i][j]+")+x3D("+A[i+1][j+1]+")>2||x3D("+A[i][j]+")+x3D("+A[i+1][j+1]+")<0||y3D("+A[i][j]+")+y3D("+A[i+1][j+1]+")>2||y3D("+A[i][j]+")+y3D("+A[i+1][j+1]+")<0||z3D("+A[i][j]+")+z3D("+A[i+1][j+1]+")>2||z3D("+A[i][j]+")+z3D("+A[i+1][j+1]+")<0");
  21.         }
  22. }

Télécharger

On peut alors retrouver les sections pentagonales et hexagonales du cube :

Les bords apparaissent souvent côtelés. Cela n’est pas dû au logiciel mais à la méthode employée : le maillage fait appel à beaucoup de points 3D ($(nbPoints+1)^2=81^2=$6 561 dans les exemples présentés plus haut), ce qui met CaRMetal à rude épreuve et impacte sans surprise sur la réactivité.

On notera que le script utilise des boucles for simplifiées, qui ont été générées par l’assistant en mode débutant (voir plus loin).

Section de cube
figure CaRMetal avec script (lancer le script section)
  • 5 solides de Platon :
    Les solides sont pilotables par leur centre (= point libre 3D), et leur dimension dépend d’une expression k modifiable.

En guise d’application, on va créer un puzzle reconstituant un cube, qui illustre le produit remarquable $(a+b)^3=a^3+3a^2b+3ab^2+b^3$

On va le faire ici par une méthode concise entièrement par script et en utilisant une macro.
C’est une méthode assez difficile, plutôt destinée à des utilisateurs experts. On pourrait arriver au même résultat avec une méthode plus simple.

Il y a 8 pavés droits à construire. On aimerait disposer d’une macro pavé, mais cette macro n’est pas d’usine. On va donc la créer.

On crée une nouvelle figure 3D.
On crée 4 points 3D A, B, C, D.
On complète le pavé en utilisant l’outil translation.
Puis on crée les 12 arêtes 3D en utilisant l’outil arête 3D.

On crée ensuite une macro pave.
Les initiaux sont A, B, C et D.
Les finaux sont tout le reste (= le pavé).
(On notera qu’il y a une orientation).

On crée ensuite 3 curseurs avec l’outil dans la palette Contrôles.
* pour a
* pour b
* t (= degré d’explosion du puzzle)

Mais on rencontre un petit problème :
Les expressions a et b sont déjà créées par l’instanciation d’une nouvelle figure 3D. On va donc utiliser c et d à la place de a et b (mais dans les commentaires qui apparaîtront, on mettra a et b, ce qui revient en quelque sorte à utiliser des alias, même si ce n’est pas le cas).

Le curseur qui affiche a=3 est un curseur nommé c.
Le curseur qui affiche b=1 est un curseur nommé d.

On crée ensuite un nouveau script.
On crée une fonction paveDroitMobile (ce pave droit utilise la macro pave, et le pavé droit créé dépend dynamiquement des paramètres c, d et t).
On crée les 8 pavés droits en lançant la fonction paveDroitMobile avec les paramètres adéquats. Et c’est terminé. Il suffit de lancer le script pour obtenir le puzzle.

Le script est le suivant :

  1. function paveDroitMobile(xA,yA,zA,dx,dy,dz,message) {
  2.         var A=Point3D(xA,yA,zA);
  3.         Hide(A);
  4.         var B=Point3D(xA+"+"+dx,yA,zA);
  5.         Hide(B);
  6.         var C=Point3D(xA,yA+"+"+dy,zA);
  7.         Hide(C);
  8.         var D=Point3D(xA,yA,zA+"+"+dz);
  9.         Hide(D);
  10.         ExecuteMacro("pave","O,X,Y,Z,"+A+","+B+","+C+","+D);
  11.         var ancre=Point3D(xA+"+"+dx+"/2",yA+"+"+dy+"/2",zA+"+"+dz+"/2");
  12.         Hide(ancre);
  13.         var text=Text(message,"x("+ancre+")-15/pixel","y("+ancre+")+30/pixel");
  14. }
  15. //PaveDroitMobile(0,0,0,"c+d","c+d","c+d");
  16. paveDroitMobile("-t","-t",0,"c","c","c","$a^3$");
  17. paveDroitMobile("c+t","c+t","c+t","d","d","d","$b^3$");
  18. paveDroitMobile("c+t","-t",0,"d","c","c","$ba^2$");
  19. paveDroitMobile("-t","c+t",0,"c","d","c","$ba^2$");
  20. paveDroitMobile("c+t","c+t",0,"d","d","c","$ab^2$");
  21. paveDroitMobile("-t","-t","c+t","c","c","d","$ba^2$");
  22. paveDroitMobile("c+t","-t","c+t","d","c","d","$ab^2$");
  23. paveDroitMobile("-t","c+t","c+t","c","d","d","$ab^2$");

Télécharger

puzzle IR (a+b)^3
figure CaRMetal avec script (lancer le script abCube).

Remarque : l’idée de départ était de le faire en programmation orientée objet en créant un objet PaveDroitMobile. Mais ici, on n’utilise plus les objets après les avoir créer.
On a donc renoncé à la programmation orientée objet, mais il reste un peu de l’idée : la fonction paveDroitMobile joue le rôle traditionnellement imparti à un constructeur. On fera réellement de la programmation orientée objet en Javascript dans l’activité suivante.


L’utilisation de la programmation orientée objet dans CaRMetal n’est pas encore très répandue. Mais elle a un potentiel considérable.
Elle permet en particulier de personnaliser les objets finaux des macros (rappelons que l’aspect des objets finaux des macros prennent l’aspect défini par défaut dans la palette aspect).

Dans cette activité, on va illustrer le pavage de l’espace par des tétraèdres et des octaèdres réguliers.
On va montrer sur la même figure :

  • qu’un tétraèdre peut être pavé par un octaèdre et des tétraèdres ;
  • qu’un octaèdre peut être pavé par des octaèdres et des tétraèdres.

Cela illustrera clairement le pavage.

  • dans le pavage du tétraèdre, on pourra déplacer les petits tétraèdres (selon le mouvement des points 3D libres dans CaRMetal 4.0) ;
  • dans le pavage de l’octaèdre, on pourra « éclater » les tétraèdres et les octaèdres en agissant sur un curseur.

De nouveau, on va tout faire par script, en utilisant des macros.
La méthode est très difficile (c’est un peu « la totale »), elle est présentée pour donner des idées et des pistes, et pas forcément pour être comprise intégralement.

On commence par créer quatre nouvelles macros en utilisants les outils de palette tétraèdre et octaèdre.
Dans ces macros, contrairement aux macros de palette, les faces polygonales seront construites.
Pourquoi 4 macros ? Parce que les outils de palette construisent des solides dans une orientation donnée, ce qui n’est pas suffisant ici.

On construit donc les macros tetraedre1, octaedre1, tetraedre2 et octaedre2.
Ces macros ont comme objet initial un point, sauf tetraedre2, qui est plus élaborée et prend aussi pour objets initiaux trois expressions, ce qui permet de construire 8 tétraèdres orientés différemment avec une seule macro.

On crée ensuite trois expressions triviales (rendues cachées), nommées « zéro », « un », « moinsUn » pour servir d’initiaux à la macro tetraedre2.
Et on crée deux curseurs nommés ecart et ecart2 pour gérer l’éclatement des tétraèdres et des octaèdres du pavage de l’octaèdre de droite.

On peut alors écrire un script en programmation orientée objet.
On crée les objets Tetraedre1, Octaedre1, Tetraedre1, Octaedre2, et on les instancie pour obtenir tous les solides des pavages.

Le script simplifié est le suivant :

  1. function Tetraedre1(x,y,z) {
  2.         this.A=Point3D(x,y,z);
  3.         SetPointType(this.A,"circle");
  4.         SetColor(this.A,"red");
  5.         SetThickness(this.A,"thick");
  6.         this.t=ExecuteMacro("tetraedre1","O,X,Y,Z,"+this.A);
  7.         SetColor(this.t[10],"blue");
  8.         SetColor(this.t[11],"cyan");
  9.         SetColor(this.t[12],"cyan");
  10.         SetColor(this.t[13],"cyan");
  11. }
  12.  
  13. function Octaedre1(x,y,z) {
  14.         this.A=Point3D(x,y,z);
  15.         Hide(this.A);
  16.         this.t=ExecuteMacro("octaedre1","O,X,Y,Z,"+this.A);
  17. }
  18.  
  19. function Octaedre2(x,y,z,e1,e2,e3,ec) {
  20.         this.A=Point3D(x+"+"+e1+"*"+ec,y+"+"+e2+"*"+ec,z+"+"+e3+"*"+ec);
  21.         Hide(this.A);
  22.         this.t=ExecuteMacro("octaedre2","O,X,Y,Z,"+this.A);
  23. }
  24.  
  25. function Tetraedre2(x,y,z,e1,e2,e3,ec) {
  26.         this.A=Point3D(x+"+"+e1+"*"+ec,y+"+"+e2+"*"+ec,z+"+"+e3+"*"+ec);
  27.         this.t=ExecuteMacro("tetraedre2","O,X,Y,Z,"+this.A+","+e1+","+e2+","+e3);
  28.         SetColor(this.t[9],"blue");
  29.         SetColor(this.t[10],"cyan");
  30.         SetColor(this.t[11],"cyan");
  31.         SetColor(this.t[12],"cyan");
  32. }
  33.  
  34. xA=3; yA=0; zA=2;
  35. tetra1=new Tetraedre1(xA,yA,zA);
  36. octa1=new Octaedre1(xA,yA,zA);
  37. tetra2=new Tetraedre1(xA+2*Math.sqrt(2)/3,yA,zA-4/3);
  38. tetra3=new Tetraedre1(xA-Math.sqrt(2)/3,yA-Math.sqrt(6)/3,zA-4/3);
  39. tetra4=new Tetraedre1(xA-Math.sqrt(2)/3,yA+Math.sqrt(6)/3,zA-4/3);
  40.  
  41. xA2=-2; yA2=1; zA2=2;
  42. octaedre1=new Octaedre2(xA2,yA2,zA2,"zero","zero","un","ecart2");
  43. octaedre2=new Octaedre2(xA2+1,yA2,zA2-1,"un","zero","zero","ecart2");
  44. octaedre3=new Octaedre2(xA2,yA2+1,zA2-1,"zero","un","zero","ecart2");
  45. octaedre4=new Octaedre2(xA2-1,yA2,zA2-1,"moinsUn","zero","zero","ecart2");
  46. octaedre5=new Octaedre2(xA2,yA2-1,zA2-1,"zero","moinsUn","zero","ecart2");
  47. octaedre6=new Octaedre2(xA2,yA2,zA2-2,"zero","zero","moinsUn","ecart2");
  48.  
  49. tetraedre1= new Tetraedre2(xA2,yA2,zA2-1,"un","un","un","ecart");
  50. tetraedre2= new Tetraedre2(xA2,yA2,zA2-1,"moinsUn","un","un","ecart");
  51. tetraedre3= new Tetraedre2(xA2,yA2,zA2-1,"un","moinsUn","un","ecart");
  52. tetraedre4= new Tetraedre2(xA2,yA2,zA2-1,"moinsUn","moinsUn","un","ecart");
  53. tetraedre5= new Tetraedre2(xA2,yA2,zA2-1,"un","un","moinsUn","ecart");
  54. tetraedre6= new Tetraedre2(xA2,yA2,zA2-1,"moinsUn","un","moinsUn","ecart");
  55. tetraedre7= new Tetraedre2(xA2,yA2,zA2-1,"un","moinsUn","moinsUn","ecart");
  56. tetraedre8= new Tetraedre2(xA2,yA2,zA2-1,"moinsUn","moinsUn","moinsUn","ecart");

Télécharger

On gère ensuite le rendu, en particulier le placement dynamique sur des calques séparés de toutes les faces de solide.

On notera qu’il y a beaucoup de CaRCommandes d’apparence, qui ne sont pas fondamentales dans le script. La POO a pour grand intérêt de structurer et d’unifier leur utilisation.

Vous trouverez le script complet dans le fichier CaRMetal ci-dessous.

pavage 3D par tétraèdres et octaèdres
figure CaRMetal avec script (lancer le script pavage).


2) Outils invisibles

  • Points sur objet

On peut créer un point sur droite/segment/... et un point sur cercle 3D.
On ne peut pas (pour l’instant) créer un point sur sphère.
Un point sur objet a bien-entendu des coordonnées 3D cohérentes.

  • Paramètres 3D et expressions CaRMetal

x3D(), y3D(), z3D() jouent le même rôle que x() et y() dans les expressions.
d3D(,) joue le même rôle que d(,).
Pour un segment (respectivement un angle) 3D, le nom du segment (resp de l’angle) dans une expression donne la longueur 3D du segment (resp la mesure 3D de l’angle).
Idem pour les vecteurs 3D et leur norme (comme en 2D).


3) Assistant de script et CaRCommandes 3D

On dispose de CaRCommandes 3D qui peuvent être générées automatiquement par l’assistant.
On notera que ce sont les mêmes CaRCommandes 2D qui permettent de créer une droite 3D, un segment 3D, etc... dans un script.
Par exemple, Line(« A »,« B ») ; crée la droite (AB), que A et B soient 3D ou pas.

Les CaRCommandes Distance et Distance3D ont été ajoutées.
Si A et B sont deux points 3D, Distance3D(« A »,« B ») donne la distance de A à B dans un script.


4) Dossier 3D de macros de menu

On dispose dans ce dossier d’un certain nombre de macros de menus (les auteurs sont Alain Busser et Yves Martin, qui ont construit les jardin suspendus de Babylone dans ce dossier).

Je vous invite en particulier à essayer la macro plan médiateur (carré ou triangle) : cette macro crée le plan médiateur sous forme d’un carré (ou triangle) dilatable piloté par un sommet.

II) Nouveautés non liées à la 3D

A) Enrichissement du Javascript disponible pour les scripts

  • Ajout de la boucle do {} until () ; non standart en javascript.

On notera le point-virgule de la fin (qui n’est pas « logique », mais indispensable).

  • Le := traditionnel de l’affectation est reconnu dans un script (traduit par = en interne).
  • Une boucle for simplifiée non standart est aussi reconnue, par exemple :
    for i from 1 to 7 {} (ou en français dans la version française de CaRMetal 4.0)

Ces ajouts de syntaxe non standard sont destinés à l’apprentissage de la programmation. On pourra consulter cet article pour trouver des exemples d’application (plutôt de niveau collège, mais pas que).

B) Le BEGINNER mode (mode débutant) de l’assistant de script

Comme son nom l’indique, il s’agit d’un mode débutant pour l’assistant de script.

Au départ, on est en mode normal. En cliquant sur le bouton (case à cocher), on passe en mode débutant.
En apparence, rien ne change. C’est seulement ce que va générer automatiquement l’assistant de script qui est modifié.

En mode normal, l’assistant génère des CarCommandes avec affectations en Javascript et une syntaxe Javascript standard (exception faite de la boucle non standard do {} until () ; )

En mode débutant :

  • si on est en français :
    • l’assistant génère des CaRCommandes en français ;
    • l’assistant génère une syntaxe en français ;
    • l’assistant génère des CaRCommandes sans affectation ;
    • l’assistant génère une syntaxe simplifiée pour la boucle for.
  • si on n’est pas en français :
    • l’assistant génère des CaRCommandes en anglais ;
    • l’assistant génère une syntaxe en anglais ;
    • l’assistant génère des CaRCommandes sans affectation ;
    • l’assistant génère une syntaxe simplifiée pour la boucle for.

On peut basculer d’un mode à l’autre en cours de rédaction du script. En fait, seules les commandes générées automatiquement sont différentes (mais elles sont reconnues quel que soit le mode).

C) Correction de bugs

Un bug important du CaRScript ExecuteMacro (bug signalé dans cet article MathémaTICE par Serge Baudet, que je remercie chaleureusement) a été corrigé.
Dans une macro avec expression, ce bug imposait de commencer par l’expression. Sinon ExecuteMacro ne fonctionnait pas. Il était par exemple impossible d’utiliser la macro de menu Rotation avec ExecuteMacro, ce qui est maintenant possible.

Deux bugs signalés par Martin Acosta sur le forum (gracias, Martin !) ont été corrigés :

  • impossibilité d’utiliser la carCommande getCONSOLE() qui permet de modifier les propriétés de la fenêtre de sortie.
  • bug (historique...) de l’Historique, qui faisait qu’un point d’arrêt était créé par défaut de type « hidebreak » (= tout le début de la construction caché).