Vous êtes sur la page 1sur 48

Description d’un objet ou de l’action qui génère un

objet:
Modélisation d’un dôme géodésique

1. Introduction

Le problème traité est celui d’encoder une méthode de conception


complètement explicite et qui est partagée par tous. On le fait par une
fonction générale qui appliquera cette méthode, selon les circonstances, pour
générer une famille d’objets de même nature, ou, ce que l’on peut appeler un
objet “ générique ” ou encore un “ archétype ”.
On remarquera que la variation de forme dans la famille obtenue dépasse
largement des variations simplement dimensionnelles ou métriques pour
admettre toutes les variantes possibles d’une même logique d’action ou de
“ savoir faire ”. Fig. 1. Première maquette réalisée durant mon cours d’architecture

Pour illustrer cette approche nous avons choisi la conception d’un dôme
géodésique. En effet ce type de structure, développé par Buckminster Fuller
est une parfaite illustration d’un processus relativement simple qui produit un
résultat extrêmement complexe. Il suffit d’avoir essayé de décrire, sur un
logiciel interactif, la forme du pavillon des États Unis à l’exposition universelle
de 1967 à Montréal, pour comprendre la difficulté de l’entreprise ! À toute fin
pratique, personne n’a réussi cet exploit de cette façon.
C’est donc un cas où la description du processus de genèse d’un objet au lieu
et place du résultat du processus, c’est-à-dire de l’objet lui-même, est
beaucoup plus performant.

Nous allons donc décrire à la fois le processus de conception d’un dôme


géodésique comme une séquence logique d’actions et de décisions et sa
mise en forme opérationnelle ou exécutable par le biais d’un langage
informatique.

Il faut dire, dès maintenant, que, dans un objectif pédagogique, nous avons
éliminé toute approche qui pouvait éventuellement être plus performante
qu’une autre si elle impliquait des connaissances préalables tant
géométriques qu’informatique qui n’étaient pas à la portée de tous. Nous
avons choisi d’être lu et compris par le plus grand nombre.

Fig. 2. Maquette virtuelle du pavillon des USA à l’exposition universelle de 1967 à Montréal

Page 1
2. Analyse générale de la nature d’un dôme géodésique En fait, tous les polyèdres réguliers inscrits à une sphère peuvent être utilisés
comme point de départ. Il faut cependant “ réduire ” au préalable les faces qui
Il existe beaucoup de formes de dômes géodésiques dont les caractéristiques ne sont pas triangulées, comme les carrés, les pentagones ou les hexagones,
ont fait l’objet de nombreuses publications. Nous référerons à un ensemble de triangles réguliers ou pas.
particulièrement le lecteur aux ouvrages de [1][2][3]. Dans tous les cas, on s’assure qu’un sommet du polyèdre et non une face ou
un segment soit situé à la verticale du centre de la sphère circonscrite au
Pour les fins du sujet, nous retiendrons les points suivants : polyèdre de façon à assurer un écoulement facile de l’eau. Cependant on
pourrait considérer que ce soit nécessaire, non au départ mais en fin de
• De façon générale, un dôme géodésique résulte d’une succession de subdivision.
subdivisions particulières d’un polyèdre régulier le plus souvent formé de
triangles.
• Celui-ci est projeté généralement sur une sphère ou quelque fois sur une
ellipsoïde ou éventuellement une surface non fermée comme une
paraboloïde ou même un cône.
• Les variantes proviennent du type de polyèdre de départ, de la nature de
la subdivision et de la fréquence adoptée, c’est-à-dire du nombre de
subdivisions successives que l’on effectue, et enfin de la surface et de la
méthode de projection retenue.
A B C
2.1. Les polyèdres de départ
Fig. 3. [A] Le tétraèdre, [B] l’octaèdre et [C] l’icosaèdre
Le monde des polyèdres est un univers en soi tellement riche qu’il n’est pas
même pas question de le survoler ici.
Nous limiterons les polyèdres de départ possibles à ceux qui sont les plus
fréquemment utilisés :

“ le tétraèdre ”, polyèdre formé de 4 triangles équilatéraux, 4 sommets et 6 arêtes,


“ l’octaèdre ”, polyèdre formé de 8 triangles équilatéraux, 6 sommets et 12 arêtes,
“ l’icosaèdre ”, polyèdre formé de 20 triangles équilatéraux, 12 sommets et 30 arêtes.

Le plus utilisé est l’icosaèdre qui est à la base du pavillon des États Unis de
l’exposition universelle de 1967,
Cependant d’autres peuvent aussi être utilisés parmi lesquels on peut citer : D F

“ Le cube ” que l’on connaît si bien,


“ le dodécaèdre ”, polyèdre formé de 12 pentagones, qui est le “ dual ” de l’icosaèdre,
c’est-à-dire celui que l’on obtient en plaçant un sommet au milieu de chaque face de
l’icosaèdre.
“ le cuboctaèdre ”, polyèdre formé de 6 carrés, et 8 hexagones, que l’on obtient en
tronquant un octaèdre par un cube.
“ le rhombicuboctaèdre ”, polyèdre formé de 18 carrés et 8 triangles, qui peut
s’obtenir en tronquant les arêtes et les sommets d’un cube, et ainsi de suite.

On peut trouver une bonne illustration des solides de Platon à l’adresse


suivante: E G
http://www.f-lohmueller.de/pov_tut/geo/geom_000f.htm
http://therese.eveilleau.pagesperso-orange.fr/pages/truc_mat/textes/platon.htm Fig.4. [D] Le cube, [E] le dodécaèdre, [F] cuboctaèdre et le [G] rombicuboctaèdre

Page 2
2.2. Les types de subdivision C’est le cas du pavillon des États Unis dont la nappe extérieure est triangulaire
et la nappe intérieure hexagonale (SUB_5).
Les subdivisions possibles sont très diverses et peuvent être classées de On remarquera que les deux premiers types de subdivision ne nécessitent la
plusieurs façon selon le domaine de connaissance dans lequel on œuvre. Pour connaissance que d’un seul triangle alors que, dans les deux suivants, il faut
des fins de production nous les classerons selon quatre types : connaître deux triangles adjacents pour pouvoir effectuer la subdivision. Il y a
donc une différence nette dans l’information requise. Dans le premier cas, une
a. La subdivision simple liste simple de triangles sera suffisante, alors que, dans le deuxième cas, il
Elle consiste à subdiviser les arêtes d’un triangle pour obtenir des sommets faudra un contrôle de nature topologique puisqu’il nécessite en entrée du
supplémentaires et à partir de ces nouveaux sommets, reformer de nouveaux processus une paire de triangles qui partagent la même arête.
triangles (fig. 5)
En partant de deux triangles de l”icosaèdre (SUB_NULL)
Une subdivision en 2 permettra de former 4 triangles pour chaque triangle
initial subdivisé (SUB_2)
Une subdivision en 3 permettra de remplacer chaque triangle initial par 9
nouveaux triangles (SUB_3)
Une subdivision en 4 revient à faire deux fois une subdivision en 2 c’est-à-dire
remplacer chaque triangle par 4 triangles qui, à leur tour, seront remplacés par
4 autres pour obtenir un totale de 16 triangles (SUB_2-2)
Toutes les subdivisions simples sont toujours des multiples de 2 et de 3 et
peuvent être obtenues par une succession des subdivisions en 2 et en 3 (2, 3,
4, 6, 8, 9, 12, 16, 18, ....). Subdivision 16 de l’icosaédre du pavillon des USA
Le pavillon des États Unis est une subdivision 16 de l’icosaèdre.
Le nombre de subdivision élémentaires appliqué successivement à un
polyèdre de départ est couramment appelé la “ fréquence ”.

b. La subdivision étoilée
Elle consiste à trouver le point de rencontre des médianes d’un triangle et de
reformer, à partir de ce nouveau sommet et de ceux existants, 3 nouveaux
triangles. Cette subdivision est souvent utilisée comme dernière subdivision
pour donner de la rigidité à l’ensemble (SUB_4).

c. La subdivision croisée (triacon)


Elle consiste à trouver le point de rencontre des médianes de 2 triangles
adjacents et de reformer à partir de ces deux nouveaux sommets et des deux
extrémités du segment commun, 2 nouveaux triangles. On pourrait tout aussi
bien utiliser la rencontre des médiatrices au lieu des médianes comme
nouveau sommet (SUB_1).

d. La subdivision étoilée et croisée


Elle consiste à effectuer sur deux triangles adjacents une subdivision étoilée et
de relier les deux nouveaux sommets entre eux et avec ceux de l’arête
commune. Ainsi 2 triangles adjacents sont remplacés par un tétraèdre. Ce type
de subdivision est utilisé comme dernière subdivision et permet d’obtenir un
dôme à deux nappes c’est à dire dont l’enveloppe a une épaisseur, une des
nappes étant de type triangulaire et l’autre de type hexagonale.
Fig. 5. Types de subdivision

Page 3
2.3. La nature de la projection

La projection est caractérisée par un centre de projection où convergent toutes


les projetantes et une surface sur laquelle on projette.
Dans la grande majorité des cas, la projection se fait sur une sphère mais il est
possible d’effectuer la projection sur une ellipsoïde pour se conformer à des
contraintes formelles que la sphère ne peut pas toujours satisfaire. On doit
remarquer que les deux volumes font parti de la famille des “ quadriques ” et
que la sphère n’est qu’un cas particulier de l’ellipsoïde. Une définition de la
surface par la dimension du demi axe en X, Y et Z permettra de spécifier
toutes les ellipsoïdes et, lorsque les trois ont la même valeur, le rayon d’une
sphère.
Cependant, par voie de conséquence, cette définition permet de spécifier
toutes les «quadriques» comme le cône elliptique, la paraboloïde ou Icosaèdre complet
l”hyperboloîde (fig.6)

Icosaèdre dont on a retiré la calotte inférieure. La base est horizontale

Fig. 6. Projection d’un icosaèdre sur une ellipsoïde et une paraboloïde

Si la projection se fait sur une sphère, elle doit être coupée quelque part pour
obtenir un dôme. Si on ne veut pas couper des membrures mais compléter
tous les triangles, le plan de coupe horizontal ne peut pas être choisi n’importe
où. Un icosaèdre, par exemple, possède deux plans horizontaux qui laissent
les triangles entiers. La suppression de la calotte du bas génèrera une
enveloppe plus grande que la demi-sphère comme celle du pavillon des États
Unis. Par contre, à la première subdivision en deux, on dispose d’un nouveau
plan horizontal qui passe par le centre de la sphère et permet d’obtenir une
enveloppe en demi-sphère (fig. 7).
Subdivision 2 de l’icosaèdre et coupe sur la demi-sphère. La base est horizontale

Fig. 7. Choix du plan de coupe d’un icosaèdre

Page 4
Le centre de projection est, en général, situé au centre de la sphère
circonscrite au polyèdre de départ. Ceci a pour effet que toute droite qui
n’appartient pas à “ l’équateur ” de la sphère sera projeté sur celle-ci selon un
cercle qui n’est pas horizontal, c’est-à-dire, qui introduira des différences de
hauteur. Ceci peut être contraignant pour asseoir un dôme sur une surface
horizontale. Pour être assuré d’avoir une base horizontale il est nécessaire que
les arêtes de la base, qui vont être projetées, le soient dans le même plan que
le centre de projection. Pour cela, il peut être nécessaire que le centre de
projection ne soit pas au centre de la sphère circonscrite au polyèdre. Certains
choisissent de déplacer verticalement le centre de projection au même niveau
que les arêtes dont ils veulent faire la base du dôme (fig. 8). Dans le pavillon
des États Unis de l”expo67, Bukmunster Fuller a choisi, pour fermer la partie
inférieure du dôme, de projeter les sommets dans le plan horizontal qui les
contient (fig 9).
Cependant cette pratique d’une projection variable selon les conditions ne
correspond pas à la pratique courante.
Il faut aussi remarquer que la projection n‘est pas toujours exécutée et que la
subdivision peut se faire directement dans le plan du triangle (fig. 10).

Fig. 10. Subdivision de l’icosaèdre sans projection

Fig. 8. Projection à partir du centre de la sphère. Projection à partir du centre du plan de coupe

Fig. 9. Double projection du dôme du pavillon des USA à partir du centre de la sphère pour Fig. 11. Projection d’un octaèdre sur la sphère circonscrite et subdivision des triangles de celui-ci
l’hémisphère nord et au niveau des arêtes pour chaque plan dans l’hémisphère sud.

Page 5
Enfin , il faut comprendre que la subdivision d’une corde ne donne pas La matérialisation peut se faire par de simples segments mais plutôt par la
nécessairement la même proportion une fois projetée que la subdivision de réalisation de panneaux à partir des triangles ou par des nœuds et tiges pour
l’arc sous-tendu par la corde. Alors a la possibilité de faire la subdivision en les sommets et arêtes de ceux-ci.
projetant le résultat à chaque étape d’une fréquence ou à la fin seulement.
Ainsi, pour diviser un segment en 4, il est possible de faire :
a) [subdivision en 2][projection][subdivision en 2][projection]
ou
b) [subdivision en 2][subdivision en 2][projection]
Les deux options ne donneront pas le même résultat (fig 9)

Ainsi la projection de BC subdivisé en deux (BDC) puis la projection de DC


subdivisé en deux (DFC) ne donne pas la même chose que la projection (CE)
du 1/4 de BC.
On remarque que les séquences successives de subdivision/projection en 2
équivalent à la subdivision de l’arc lui-même dans un multiple de 2.
Par contre la projection de la subdivision d’une corde en 3, ne correspond pas
à la subdivision de l’arc en 3.
De même une subdivision en 3 suivie d’une subdivision en 2 ne donne pas le
même résultat qu’une subdivision en 2 suivie d’une subdivision en 3.

Il serait alors possible de subdiviser le segment dans un rapport tel que sa


projection divise l’arc en parties égales.

Fig. 12. Stratégie des séquences de subdivision Fig. 13. Matérialisation possible

Page 6
3.Stratégie informatique Pour ce faire, nous devons partir des deux sommets d’un segment (1&2) pour
repérer dans la liste tous ceux qui ont un sommet identique. Du segment
Devant la diversité des options, que ce soit le polyèdre de départ, le centre et trouvé on refait la même opération et finalement on vérifie si un des sommets
la surface de projection, comme de type de projection, il est difficile de trouver dans cette dernière liste est identique au deuxième sommet du segment initial.
un principe mathématique ou géométrique unique qui permette de construire En éliminant la recherche et la vérification de paires similaires comme le
tous les cas observés. segment 1-2 et le segment 2-1, ainsi que le lien vers soi-même (le point 1 du
Au lieu de restreindre les possibilités pour optimiser le processus, nous avons segment 1-4 est lié au point 4), il faut encore faire la recherche suivante pour
opté pour une approche plus large encore qui permettra de générer toutes les identifier les deux triangles (1-2-4 & 1-3-4) auxquels le segment appartient:
variantes décrites et plus.
En effet, la solution qui apparait la plus générale consiste à bâtir des fonctions segment recherche1 recherche2 test
de subdivisions de triangles qui sont indépendantes de la sphère et donc non 1-4 1-2 2-4 oui
géodésiques, qui permettent d’effectuer un «maillage» triangulaire de 2-5 non
n’importe quelle quadrique selon n’importe quelles règles. 1-3 3-6 non
Dans ce cadre, le point de départ est une liste de triangle et le retour une autre 3-7 non
liste de triangles obtenus à partir de la première liste par une fonction 3-4 oui
quelconque de transformation. De même, cette géométrie sera matérialisée
par des fonctions volumiques qui la matérialisera par des membrures, nœuds
ou panneau selon le cas.

Puisque tout le traitement se fera sur des triangles, il faut d’abord évaluer la
façon de les représenter:

Les données, à quelque niveau de subdivision que ce soit, comprennent


essentiellement des “ sommets ”, qui peuvent être considérés comme des
points dans l’espace et des “ arêtes ” qui représentent des liens particuliers
entre les sommets et qui, eux même, définissent des faces triangulaires. On
peut donc envisager, à priori, 3 grandes possibilités selon qu’on approche
l’information à retenir et traiter comme étant des sommets, des arêtes ou des
faces. Pour illustrer les possibilités, prenons, par exemple, une résille de 5
triangles, 7 sommets (1,2,3,...,7) et 11 segments (1-2, 1-4, 2-5,...). (fig. 13)

3.1. Approche par sommets


Une approche uniquement basées sur des points ne nous permet pas de
déduire l’appartenance de ces points à une entité logique à moins d’y associer
un indice unique selon un formalisme qui peut s’avérer complexe puisqu’il doit
permettre de repérer, à posteriori, les triangles (jusqu’à 6) et segments
( jusqu’à 9) auxquels un point appartient.

3.2. Approche par arête


Une approche uniquement basée sur des segments nous oblige à reconstruire
leur appartenance à des triangles.

Fig. 13. résille de triangles

Page 7
3.3. Approche par faces. Dans le cas du triangle (3 6 7), il apparaît trois fois :
((3 7 4)(3 6 7)) pour l’arête 3-7
Enfin une approche uniquement basée sur des triangles permet de traiter ((3 6 7)) pour l’arête 3-6
directement chaque triangle comme entité individuelle du moins tant que l’on ((3 6 7)) pour l’arête 6-7
se limite à des subdivisions du premier type. Une écriture plus utile consisterait à adopter un format où l’arête étudiée serait
Dans ce cas, une liste de triangles initiaux, subdivisés en deux ou en trois, en premier à savoir :
retournera, après traitement, une nouvelle liste où chaque triangle initial sera [g] ((3 7 4)(3 7 6))((3 6 7))((6 7 3))
remplacé par trois où neuf triangles selon la subdivision en 2 ou en 3 et éviter ainsi un traitement ultérieur pour reconnaître l’arête que ces deux
demandée. triangles partagent..
Après chaque subdivision, on revient donc à une nouvelle liste de triangles qui
peut être traitée, à nouveau, de la même façon. On est donc dans une situation
d’appel récursif de fonction, c’est à dire de fonction qui se rappelle elle-même
en mettant à jour ses paramètres d’entrée au fur et à mesure.
Les subdivisions faites, il faut cependant traiter géométriquement des sommets
par une forme particulière de nœuds et les arêtes par une forme particulière de
membrures.
Il faut donc extraire les sommets et les arêtes de la liste de triangles.
Dans le cas de la figure [13], la transformation simple d’une liste de triangles
[a] en sommets [b] donnera :
[a] ((1 3 4)(1 4 2)(2 4 5)(3 7 4)(3 6 7)) ->
[b] (1 3 4 1 4 2 2 4 5 3 7 4 3 6 7)
Il faudra réduire la liste pour éliminer les doublets
[c] (1 3 4 2 5 7 6)
De même, l’extraction simple des segments donnera :
[d] ((1 3)(3 4)(4 1)(1 4)(4 2)(2 1)(2 4)(4 5)(5 2)(3 7)(7 4)(4 3)(3 6)(6 7)(7 3))
Il faudra aussi réduire la liste pour éliminer les doublets sachant que (1 2) & (2
1) décrivent le même segment
[e] ((1 3)(3 4)(4 1)(4 2)(2 1)(4 5)(5 2)(3 7)(7 4)(3 6)(6 7))

Par contre, pour les subdivisions qui nécessitent de connaître deux triangles
adjacents pour les traiter, il faut reconnaître dans la liste de triangles ceux qui
partagent une arête.
Ainsi pour chaque segment [x] de la liste [e], on cherchera dans la liste [a]
l’élément [y] qui contient les deux termes de [x] :
(1 3) -> (1 3 4) soit une liste à un seul triangle -> ((1 3 4 ))
(3 4) -> (1 3 4) & (3 7 4) soit une liste à deux triangles -> ((1 3 4)(3 7 4))

le traitement donnera la liste finale suivante :


[f] (((1 3 4))((1 3 4)(3 7 4))(( (1 3 4)(1 4 2))((1 4 2)(2 4 5))((1 4 2))((2 4 5))((2 4
5))((3 7 4)(3 6 7))((3 7 4))(3 6 7))((3 6 7)))

On voit que dans cette liste, les segments peuvent être communs à deux
triangles ou à un seul selon leur situation.

Fig. 13. résille de triangles

Page 8
3.4. l’information pour la mise en forme physique De façon générale, un indice explicite, associé à une donnée, permet de
qualifier les données et donc permet de regrouper, trier, filtrer ce que l’on veut
Quelque soit l’approche, il faut être à même, pour chaque segment, sommet, selon l’encodage choisi. La gestion en est cependant plus lourde.
ou face de parfaitement s’orienter dans l’espace pour pouvoir le réaliser par le Pour éviter cette gestion explicite mais générale on peut utiliser un indice
biais d’une forme spécifique. implicite basé sur la position d’un élément dans une liste.
Pour traiter une membrure sous toutes ses formes possibles nous devons Ainsi, dans l’exemple précédent, l’enregistrement prendra la forme suivante :
connaître le segment à investir mais aussi les deux plans adjacents ainsi que
le plan formé par le segment et le centre qui se trouve être le plan bissecteur Liste de points :
des deux plans adjacents. La capacité de retrouver, dans un traitement par ((-52.57311121191336 85.065080835204 161.80339887498948 1)
triangles ceux qui sont adjacents à une arête permettra de le faire. Ainsi dans (52.57311121191336 -85.065080835204 161.80339887498948 1)
la liste [f], l’élément ((3 7 4)(3 7 6)) pourra devenir les données d’un tétraèdre (137.63819204711737 85.06508083520399 100. 1)
qui fournira tout ce qui est nécessaire. (-137.63819204711737 -85.06508083520399 100. 1))
((3 7 4)(3 7 6)) -> (3 7 4 6) -> plan 3-7-4, plan 3-7-6, plan 3-7-centre de
projection. Liste de triangles :
((1 2 3)(1 2 4))
3.5. l’identification
Cette approche est plus compacte mais nécessite de gérer parfaitement l’ordre
La mémorisation d’un point nécessite d’enregistrer 4 coordonnées qui peuvent des points puisque c’est sur la base de sa position dans une liste que l’on
être 4 nombres réels importants. identifiera un point spécifique. Dans ce cas, il est à noter que toute
À titre d’exemple voici la liste des 4 sommets définissant les deux triangles qui suppression d’un élément dans la liste change l’indice des éléments qui
ont servis d’illustration des types de subdivision (fig. 13): suivent, ce qui n’est pas le cas d’indices explicites.

(#(-52.57311121191336 85.065080835204 161.80339887498948 1) On remarque aussi que le choix d’indices implicites rend la conservation de
(#(52.57311121191336 -85.065080835204 161.80339887498948 1) l’historique des événements plus complexe. Par exemple, un indice explicite
(#(137.63819204711737 85.06508083520399 100. 1) pour identifier des triangles pourrait servir à identifier la filiation de la
(#(-137.63819204711737 -85.06508083520399 100. 1)) subdivision comme par exemple :

Or, dans une liste de triangles, un sommet particulier peut être répété jusqu’à ((a triangle_1) (b triangle_2)) ->
9 fois puisqu’il peut appartenir à 9 triangles différents. On imagine tout de ((aa triangle_1)(ab triangle_2)(ac triangle_3)(ad triangle_4)(ba triangle_5)(bb
suite la mémoire qu’il va falloir utiliser pour décrire les triangles sous cette triangle_6) ....) ->
forme. ((aaa triangle_1)(aab triangle_2) ... (bdd triangle_32)) -> et ainsi de suite.
Il y a donc un net avantage à ne pas dupliquer l’enregistrement des
coordonnées des sommets c’est à dire à séparer la liste des sommets de la Ainsi le triangle 32 est identifié comme le 4ème triangle du 4ème triangle du
définition des triangles. Il suffit pour cela d’établir une liste de points 2ème triangle de départ.
identifiables par un indice et d’y référer dans une liste de triangles par le biais
de l’indice :

Liste de points :
((a -52.57311121191336 85.065080835204 161.80339887498948 1)
(b 52.57311121191336 -85.065080835204 161.80339887498948 1)
(c 137.63819204711737 85.06508083520399 100. 1)
(d -137.63819204711737 -85.06508083520399 100. 1))

Liste de triangles :
((a b c)(a b d))

Page 9
3.6. Les répétitions 4. ORGANISATION DU PROGRAMME

Une subdivision strictement géodésique d”un polyèdre régulier génère des La structure du programme est définie par deux termes, la structure des
«patterns» de répétition. Au départ, les 20 triangles de l’icosaèdre sont fichiers manipulés et l’organisation des fonctions qui les traitent ou les
identiques hormis leur position dans l’espace. Aussi chacun peut référer au génèrent.
même «objet» et s’individualiser par une séquence particulière de rotation.
Toute subdivision géodésique de cet «objet» de référence peut être reproduite 4.1. La structure des fichiers
dans l’espace par la même séquence.
Nous avons retenu de représenter l’information par le biais de points uniques
Ainsi toute projection de polyèdre régulier peut s’obtenir par la description d’un sous forme de coordonnées et par des triangles sous forme de symboles
seul élément (triangle équilatéral, carré, pentagone, hexagone) et des groupes numériques référant à la position des sommets dans la liste de points. Or les
de symétrie (matrices) nécessaires pour obtenir les autres. Ainsi la subdivision fonctions peuvent accepter un nombre variable de paramètres en entrée mais
d’un élément sera reporté par simple multiplication matricielle sur l’ensemble ne renvoient que le dernier résultat c’est-à-dire une seule information.
de la sphère. C’est pourquoi nous avons adopté un formalisme d’une seule liste de 2
Cependant la projection par différents centres et sur différentes surfaces membres, une liste de points (liste de 4 coordonnées) et une liste de triangles
rendent cette approche impraticable. C’est pourquoi nous opterons pour un (liste de 3 symboles).
traitement géométrique individualisé de chaque triangle.
(liste (liste point1, point2, ... ,pointn)(liste triangle1, triangle2, ... ,trianglen))
Pour les fins de l’illustration nous retiendrons la stratégie générale suivante : Exemple: représentation d’un octaèdre de 100 unités de côté
(
(
a) la morphologie sera décrite par des listes de triangles.
#(0 70.71067811865474 0 1)
b) La description des triangles se fera sous une forme symbolique. Ce
#(-70.71067811865474 0 0 1)
symbole, de type numérique, identifiera chaque point par sa position dans
#(0 0 70.71067811865474 1)
une liste de points uniques.
#(70.71067811865474 0 0 1)
c) Les coordonnées des points seront consigné dans une liste unique de
#(0 0 -70.71067811865474 1)
points.
#(0 -70.71067811865474 0 1)
d) L’adjacence des triangles sera obtenue par traitement de la liste de
)
triangles.
(
e) La liste des arêtes sera obtenue par traitement de la liste des triangles.
(1 2 3) (1 3 4) (1 4 5) (1 5 2) (6 3 2) (6 4 3) (6 5 4) (6 2 5)
f) La mise en forme des nœuds se fera par une sphère dont le centre est au
)
point considéré
)
g) La mise en forme des membrures se fera par un cylindre entre deux
sommets.
h) La mise en forme des faces se fera par un triangle d’épaisseur donnée.
i) Tout autre mise en forme doit rester possible.

Page 10
4.2. les fonctions Cette organisation a plusieurs avantages:

Nous allons organiser le programme selon opérations suivantes: Le travail propre au traitement géométrique (sommets, arêtes et projections)
peut être fait indépendamment de toute matérialisation physique (noeuds,
1. (GEN_xxx arête fichier_géométrique) membrures ou panneaux) et servir d’entrée à diverses formalisations sans
Ce sont des fonctions qui génèrent les données géométriques de nécessiter la reprise du calcul. Ce fichier géométrique (points et triangles) peut
polyèdres réguliers selon de la valeur de l’arête et qui les écrit dans un être combiné à d’autres. Ceci permet, entre autre, de réaliser le pavillon des
fichier géométrique. États Unis dont l’hémisphère supérieure est faite d’une façon alors que le reste
est fait d’une autre ce qui implique deux traitements différents. De même un
2. (GEOM_DEF fichier_géométrique_entrée fichier_géométrique_sortie) calcul d’envergure peut, à la limite, être traité en plusieurs passes.
Cette fonction permet de définir les paramètres de traitement géométrique
des données, de lancer leur exécution et d’écrire le résultat géométrique Le fichier volumique peut à son tour être repris pour générer diverses images
dans un fichier de sortie. selon le point de vue ou la lumière sans reprendre le calcul. Cela permet aussi
de combiner divers objets calculés dans une scène plus générale. Par
3. (GEOM_EXE data_géométriques paramètres d’exécution) exemple, on pourra combiner les fichiers du dôme du pavillon des États Unis
Cette fonction traite les données géométriques selon les paramètres avec celui de sa base ou des bâtiments qu’il enveloppe pour générer une
d’exécution définis précedemment et retourne de nouvelles données scène plus complète.
géométriques
On a donc une structure de génération et de contrôle par étape qui permet plus
4. (VOLU_DEF fichier_geométrique fichier_volumique) de souplesse pour atteindre les divers objectifs que l’on s’est fixé.
Cette fonction permet de définir les paramètres de matérialisation
physique des données géométriques, de lancer l’exécution des solides et Enfin, la quantité de paramètres à définir pour rendre compte de toutes les
d’écrire le résultat volumique dans un fichier sortie. options possibles, ne permettait pas d’appeler des fonctions paramétrées.
Aussi ces choix sont possibles en éditant un fichier Scheme ou chaque
5. (VOLU_EXE data_géométriques paramètres d’exécution) paramètre est défini, modifiable et explicité.
Cette fonction traite les données géométriques selon les paramètres
d’exécution définis précedemment et retourne un fichier volumique. (GEODESIC)
Défini les tâches comme l’exécution d’un fichier géométrique, volumique ou
6. (VUES_DEF data_volumiques) d’une image. Elle permet de nommer les fichiers d’entrée et de sortie pour
Cette fonction permet de définir les paramètres de visualisation d’un usage ultérieur ou de lancer le tout en chaîne.
volume et construit l’image correspondante qu’elle écrit dans un fichier.
(GEOM_DEF)
7. (GEODESIC) Défini les paramètres de traitement géométrique comme la séquence et les
types de subdivision, la quadrique de projection et le centre de projection.
Au sommet de cette organisation, on aura une fonction générale, sans
paramètres, qui permet de définir les tâches à exécuter ainsi que définir (VOLU_DEF)
les fichiers d’entrée/sortie de chaque tâche générale. Défini les paramètres volumiques comme la couleur et le rayon des nœuds ou
des membrures ainsi que l’épaisseur, la couleur et le type de panneaux

(VUES_DEF)
Défini la scène comme la position de l’observateur, le centre de visée, le cône
de vision et la grandeur de l’image ainsi que sa matérialisation par un affichage
sur l’écran ou l’écriture d’un fichier bitmap.

Page 11
5. Le pavillon des USA de Buckminster Fuller à l’exposition
universelle de Montréal en 1967.

Pour illustrer ces fonctions on s’est donné le défi de modéliser le pavillon des
USA de Buckminster Fuller. On a remarqué que les plans originaux ne
montrent jamais le dôme dans son ensemble mais seulement une
représentation à une seule couche, en plan et élévation, ou une partie du
dôme aplatie ayant pour centre un des pentagones. Ceci pour dire que le
dôme a été calculé mais jamais représenté.
Le dôme est basé sur la projection d’un icosaèdre sur une sphère avec une
subdivision de 16 en itérations de 2 soit 4 fois 2: [2 2 2 2].
Il est construit en 2 nappes, la deuxième nappe étant bâtie sur la médiane des
triangles de la première nappe. La modélisation a été faite avec une couche en
premier lieu puis avec 2 couches toujours avec des triangles pleins. Puis
diverses représentations ont été générées avec des nœuds et membrures.

Page 12
Documents originaux

Page 13
Photos de l’exposition en 1967

Page 14
Photos de l’exposition en 1967

Page 15
Modélisation à 1 nappe

Page 16
Modélisation à 2 nappes
13800 nœuds, 34323 membrures

Page 17
Page 18
BIBLIOGRAPHIE: GEO_LOAD.scm

Cette fonction sert à charger toutes les fonctions nécessaires au traitement


[1] Gheorghiu Adrian, Dragomir Virgile, La représentation des structures géométrique choisi quelque soit le traitement, ainsi que les fonctions
constructives, Editions Eyrolles, Paris, 1968 susceptibles d’être appelées comme H_REF1.
[2]McHale John, R.Buckminster Fuller, George Braziller, New York, 1962
[3]Kenner Hugh, Geodesic math and how to use it, University of California
Press, Berkeley and Los Angeles, 1976 —————————————————————————————————————
[4]Potter Robert R., Buckminster Fuller, Silver Burdet Press, 1990 ; GEO_LOAD
[5] Hjersman Peter, Dome Notes, Erewon Press, 1975 ; fichier de chargement des fonctions nécessaires pour la génération
[6]Sheppard Roger, Treadgill Richard, Holmes John, Paper Houses, Schocken ; géométrique d’un dôme géodésique
;—————————————————————————————————————
Books, New York, 1974 (define geo_load
[7] Prenis John, The dome builder’s Handbook, Running Press, Philadelphia, (lambda ()
1973 (begin
(load “ellipsoi.scm”)
(load “cone.scm”)
(load “parabolo.scm”)
(load “geom_exe.scm”)
(load “subloop2.scm”)
(load “sub1.scm”)
(load “sub10.scm”)
Annexe: Description des programmes (load “sub11.scm”)
(load “sub12.scm”)
(load “sub20.scm”)
(load “sub21.scm”)
Toutes les fonctions écrites en Scheme sont décrites pour ceux qui souhaitent (load “sub22.scm”)
voir comment le traitement informatique est fait (load “sub30.scm”)
(load “sub31.scm”)
(load “sub32.scm”)
(load “sub40.scm”)
(load “sub41.scm”)
(load “add_pts.scm”)
(load “add_tri.scm”)
(load “cootosym.scm”)
(load “symtocoo.scm”)
(load “elimine.scm”)
(load “voisin.scm”)
(load “adjacent.scm”)
;———————————————————————————————- (load “medianes.scm”)
;DATA_gen (load “mediane0.scm”)
;fonction de chargement des fonctions qui génèrent des polyèdres (load “reforme.scm”)
;réguliers (icosaèdre, octaèdre, tétraèdre) (load “triordre.scm”)
;———————————————————————————————- (load “verifier.scm”)
(define data_gen (load “verifie0.scm”)
(lambda() (load “projecti.scm”)
(begin (load “tripoint.scm”)
(load “gen_ico.scm”) (load “tri_seg.scm”)
(load “gen_oct.scm”) (load “add_seg.scm”)
(load “gen_tet.scm”) (load “h_ref1.scm”)
) )
) )
) )
;———————————————————————————————- ;—————————————————————————————————————
;COMMENTAIRES:
;———————————————————————————————-

Page 19
;———————————————————————————————
GEODESIC.scm ;GEODESIC
;lance l’exécution de l’ensemble de la génération d’un dôme
C’est une fonction générale qui permet le contrôle des tâches à faire et des ;par succession de fichiers.
;pour chaque niveau, on indique:
fichiers d’entrée-sortie de ces tâches: ;l’execution 0->non, 1->oui
;le nom du fichier de départ ou la fonction qui l’exécute
1. La géométrie (exec_dat) attend et retourne un fichier géométrique, ;le nom du fichier de sortie
((liste points)(liste triangles)), après traitement (projection, subdivision, ;fich_dat: pour le traitement géométrique (sommets, segments)
;fich_sol: pour la matérialisation volumique (nœuds, membrures)
élimination)
;fich_vue: pour la construction de l’image (projection, lumière)
;fich_tga: pour l’enregistrement d’une image pixel format targa.
2. La volumique (exec_sol) attend un fichier géométrique et renvoie un ;———————————————————————————————-
fichier volumique (PIgen). (define geodesic
(lambda ()
(load “data_gen.scm”)
3. La visualisation (exec_vue) attend un fichier volumique et renvoie un (data_gen)
calcul de vue (PIshow). (let
(
(fich_ori “icosaedre.dat”)
4. L’image (exec_img) attend un calcul de vue et retourne l’affichage sur
(exec_dat 1)
l’écran ou l’écriture d’un fichier Targa (PIview, PItarga). (fich_dat “panneau.dat”)
(exec_sol 1)
(fich_sol “panneau”)
(exec_vue 1)
(fich_vue “panneau”)
(exec_img 1)
(view 0)
(fich_tga “panneau”)
(tga 1)
)
;-------------------------
(if
(= 1 exec_dat)
(begin
(load “geom_def.scm”)
(geom_def fich_ori fich_dat)
)
(begin
(newline)
(display “*** PAS DE CALCUL GEOMETRIQUE ***”)
(newline)
)
)
;-------------------------
(if
(= 1 exec_sol)
(begin
(load “volu_def.scm”)
(volu_def fich_dat fich_sol) )
(begin
(newline)
(display “*** PAS DE CALCUL VOLUMIQUE ***”)
(newline)
)
)
;-------------------------

Page 20
(if XXX_DEF.scm
(= 1 exec_vue)
(begin
Le nombre d’options nécessaires pour la définition d’un dôme géodésique particulier, à
(load “vues_def.scm”)
savoir la nature du traitement géométrique, le type de concrétisation physique et le choix
(vues_def fich_sol fich_vue fich_tga view tga)
de la vue, est trop élevé pour pouvoir être mis en paramètre d’une fonction générale.
)
C’est pourquoi nous avons opté, pour définir ces paramètres, de le faire à l’intérieur
(begin
même de la première fonction qui lance une tâche. Ainsi, à chaque tâche exécutable,
(newline)
définie dans “GEODESIC”, correspond une fonction dont l’édition permet de spécifier les
(display “*** PAS DE CALCUL D’IMAGE ***”)
paramètres de ce traitement:
(newline)
Géométrique -> GEOM_DEF.scm
)
Volumique -> VOLU_DEF.scm
)
Visualisation -> VUES_DEF.scm
;-------------------------
Image -> IMAG_DEF.scm
(if
(= 1 exec_img)
Pour chacune de ces tâches, un “LET” permet à l’usager de définir les valeurs des
(begin
variables de traitement. La fonction charge l’ensemble des fonctions nécessaires au
(load “imag_def.scm”)
traitement spécifique à la tâche et lance son exécution. Ainsi n’est chargé en mémoire
(imag_def fich_vue fich_tga view tga)
que les fonctions nécessaires au choix des tâches à exécuter décidé dans “GEODESIC”.
)
Selon le travail à faire, on doit éditer ces fichiers pour spécifier les paramètres du travail.
(begin
L’ensemble des paramètres étant fixés, ces fonctions appellent les fonctions qui vont
(newline)
exécuter la tâche en leur transmettant la valeur définie des paramètres.
(display “*** PAS D’IMAGE ***”)
(newline)
)
)
;-------------------------
)
)
)
;——————————————————————————————————
;COMMENTAIRES:
;geom_def règle les paramètres géométriques (fréquence, traitement)
;volu_def règle les paramètres physiques (nœuds, membrures, panneaux)
;vues_def règle les paramètres scéniques (point de vue, lumières,..)
;imag_def règle l’exécution de l’affichage de l’image
;data_gen contient les fonctions de génération des données des
; polyèdres réguliers avec pour paramètre l’arête:
; (data_ico)(data_oct)(data_tet)...
;——————————————————————————————————

Page 21
GEOM_DEF.scm (define geom_def
(lambda
Fonction qui permet de spécifier les paramètres du traitement géométrique. Elle a, en (dat_in dat_out)
entrée et sortie, le même type de fichier soit une liste de 2 élements, une liste de points et ;;chargement des fonctions nécessaires
une liste de triangles. Les deux sont des fichiers de données lus ou écrits. (load “geo_load.scm”)
“DATA” reconstitue en mémoire le fichier d’entrée (dat_in) (geo_load)
“IT” spécifie la séquence de subdivision sous forme d’une liste à traiter. ;;définition des parametres
QUAD0 spécifie la quadrique principale de projection, celle sur laquelle seront les (let*
sommets des dômes à une nappe. (
QUAD1 spécifie la quadrique secondaire de projection, celle sur laquelle seront les (fich_in (open-input-file dat_in))
sommets de la 2ème nappe. (fich_out (open-output-file dat_out))
Pour spécifier ces quadriques, on appelle les fonctions au choix: (data (read fich_in))
(ellipsoi ox oy oz) ;;sequence de subdivision (voir commentaires)
(parabolo ox oy oz) (it (list 1))
(cone ox oy oz) ;;définition des quadriques de projection
qui permettent de spécifier des ellipsoïdes, sphères, paraboloïdes et cônes elliptiques ou ;;(quad0->1er nappe, quad1-> 2ème nappe)
circulaires. (quad0 (ellipsoi 125 125 125))
P_PROJ spécifie le centre de projection, en général 0 0 0 1 (quad1 (ellipsoi 121.5 121.5 121.5))
P_MOIN & P_PLUS spécifient respectivement les hauteurs à partir desquelles on élimine ;;données de projection: centre de projection, niveau de coupe
les triangles totalement en dessous et au dessus de ces références. (p_proj (vector 0 0 0 1))
(p_moin 0)
Ces données sont envoyées à GEOM_EXE.scm pour exécution. (p_plus 160)
)
Traitement en référence avec l’analyse faite précédemment: ;;ecriture des données du dome
1. C’est une simple projection sur quad0 à partir du centre de projection. (newline)
1x. C’est une subdivision basée sur la médiane de chaque triangle traité. Chaque arête (display “*** EXECUTION DU FICHIER GEOMETRIQUE ***”)
commune à deux triangles adjacents est remplacée par 2 triangles formés des deux (newline)
médianes et des sommets de l’arête. (write (geom_exe data it quad0 quad1 p_moin p_plus p_proj) fich_out)
2x. C’est une subdivision en 2 de chaque arête de chaque triangle traité. Elle renvoie 4 (close-input-port fich_in)
triangles. (close-output-port fich_out)
3x. C’est une subdivision en 3 de chaque arête de chaque triangle traité. Elle renvoie 9 (display “*** FIN D’EXECUTION DU FICHIER GEOMETRIQUE ***”)
triangles. (newline)
4x. C’est une subdivision à partir de la médiane de chaque triangle. La médiane et les 3 )
sommets forment 3 triangles. )
x0. La subdivision est faite dans le plan du triangle initial. )
x1. La subdivision est projetée sur quad0 ou quad1 à partir du centre de projection ;——————————————————————————————————
spécifié. ;COMMENTAIRES:
x2. La subdivision est projeté sur quad0 horizontalement c’est-à-dire à partir de 0, 0, y du ;quadriques possibles:
point traité, 1 ;(ellipsoi ox oy oz)(parabolo ox oy oz)(cone ox oy oz)
ou sur quad1 à partir du centre de projection. ;subdivisions possibles:
12. cas d’une dôme à double nappe. ;1 projection des points sur quad0 a partir du centre de projection
;0 élimination des triangles totalement en dessous de p_moin
; élimination des triangles totalement au dessus de p_plus
;10 mediane dans le plan du triangle, triangle initial perdu
;11 mediane projetée sur quad0. triangle initial perdu
;12 2 nappes, medianes jointes sur quad1, triangle initial conservé
;20 subdivision en 2 dans le plan du triangle initial
———————————————————————————————— ;21 subdivision en 2 projeté sur quad0
;GEOM_DEF ;22 idem mais projection horizontale
;permet de définir et construire la geométrie du dome ;30 subdivision en 3 dans le plan du triangle initial
;parametres: ;31 subdivision en 3 projeté sur quad0
;dat_in fichier de données de départ ;32 idem mais projection horizontale
;dat_out fichier d’écriture des résultats ;40 mediane dans le plan du triangle, triangle initial conservé
;retour: ;41 medianne projetée sur quad1, triangle initial conservé
;fichier “(list (list pt)(list tri))” ;(h_ref1 arete quad0 p_proj):
;———————————————————————————————— ; fonction qui renvoie la hauteur du “tropiques+” de l’icosahèdre
;——————————————————————————————————-

Page 22
HREF1.scm
Cette fonction sert à calculer la hauteur du “tropique+” d’un icosaèdre. En effet, plusieur dômes,
dont celui des États Unis, sont des “3/4” de sphère, c’est à dire sont coupés à la hauteur de la
2ème calotte de l’icosaèdre. Pour spécifier cette hauteur, on utilise un point de référence (d) des
données de départ et on le projète sur quad1 à partir du centre de projection.
Cette fonction permet de spécifier p_moin dans ce cas particulier.

;——————————————————————————————-
;H_REF1
;hauteur de reference de l’icosaèdre de base (tropique+)
;——————————————————————————————-
(define h_ref1
(lambda
(arete quad proj)
(let*
(
(q (/ arete 2))
(r (/ arete (- (sqrt 5) 1)))
(rot (atan (/ q r)))
(d (vector r 0 (- q) 1))
)
(vector-ref
(SGx__euc
(projecti
quad
(vector-ref
(SGmatpro
(vector d)
(SGmat001 (vector rot 1))
)
0)
proj)
)
1)
)
)
)
;———————————————————————————————
;COMMENTAIRES:
;———————————————————————————————

Page 23
VOLU_DEF.scm ;—————————————————————————————————————
;VOLU_DEF
;définition volumique du dôme géodésique
Cette fonction permet de définir la matérialisation du fichier géométrique avec des
;parametres:
volumes, de lancer son exécution et d’écrire le résultat dans un fichier.
;vg liste des parametres d’execution
;sortie fichier sl
DATA_GEO ->fichier géométrique d’entrée.
;—————————————————————————————————————
SOL_GEO ->fichier volumique (*.sl)
(define volu_def
DATA, récupération en mémoire des données d’entrée.
(lambda (data_geo sol_geo)
POINTS, identification de la liste des points
(load “vol_load.scm”)
TRIANGLES, identification de la liste des triangles
(vol_load)
(let*
Les paramètres à définir sont:
(
;;récupération des données d’entrée
C_SPH, R_SPH, la couleur et le rayon des sphères qui matérialisent les sommets en
(fich_in (open-input-file data_geo))
nœuds.
(data (read fich_in))
C_CYL, R_CYL, la couleur et le rayon des cylindres qui matérialisent les arêtes en
(points (car data))
membrures.
(triangles (cadr data))
C_PAN, EP, la couleur et l’épaisseur des panneaux qui matérialisent les triangles.
;;couleur et rayon des sphères
LA, la largeur de la partie pleine du panneau qui reste lorsque celui-ci est troué.
(c_sph (vector 0 250 60 255))
TV, le choix cumulatif du traitement volumique choisi.
(r_sph 0.5)
(On peut rajouter autant d’options que de nouvelles façon de matérialiser les données
;;couleur et rayon des cylindres
géométriques !)
(c_cyl (vector 0 120 180 255))
QUADMNX, défini le minmax de la scène:
(r_cyl 0.3)
On peut utiliser la quadrique de projection lorsque c’est approprié (ellipsoïde, paraboloïde
;;couleur, épaisseur et “largeur” des panneaux
ou cône). Mais on peut utiliser aussi la fonction MIN_MAX.scm d’une liste de points qui
(c_pan (vector 0 120 180 255))
permet de trouver un minmax à un ensemble de points.
(ep 2)
VG, liste de l’ensemble des paramètres définis.
(la 10)
;;choix du traitement volumique
Ces données sont envoyées à VOLU_EXE pour exécution.
;; 1 :”noeud”
;; 2 :”membrure”
;; 3 :”panneau_plein”
;; 4 :”panneau_troue”
(tv (list 1 2))
;définition du minmax général
(quadmnx (DLformz2 (ellipsoi 154 154 154)))
;mis en liste de l’ensemble des parametres d’exécution
(vg
(list points triangles c_sph r_sph c_cyl r_cyl c_pan ep la tv quadmnx)
)
)
(close-input-port fich_in)
(newline)
(display “*** EXECUTION DU FICHIER VOLUMIQUE ***”)
(newline)
(PIgen (volu_exe vg) sol_geo)
(display “*** FIN D’EXECUTION DU FICHIER VOLUMIQUE ***”)
(newline)
)
)
)
;—————————————————————————————————————
;COMMENTAIRES:
;1. une sphère est placée à chaque sommet
;2. Un cylindre est placé à chaque arête de triangle
;3. Un panneau plein est construit pour chaque triangle
;4. Un panneau percé au centre est construit pour chaque triangle
;—————————————————————————————————————
Page 24
VUES_DEF.scm IMAG_DEF.scm
Cette fonction permet de définir les paramètres de la scène qui vonst s’appliquer aux Cette dernière fonction ne sert pas vraiment à “définir” les paramètres d’exécution d’une
données volumiques pour générer une “vue” particulière. vue puisque les choix sont faits à même “GEODESIC”.
Deux fichiers sont en paramètre: C’est plutôt une fonction d’exécution.
SOL_GEO, le fichier volumique à traiter Cependant il était plus pratique de réduire les endroits de décision lorsque cela était
IMG_GEO, le fichier de scène généré possible.
VIEW & TGA indiquent (0 ou 1) si l’affichage doit être fait ou l’écriture d’un fichier Targa.
Cette valeur est déterminée dans “GEODESIC”.
TGA_GEO donne le nom du fichier Targa à écrire si nécessaire. ;———————————————————————————————————-
;IMAG_DEF
PIsobs, position de l’observateur ;génère l’affichage de la vue
PIstarget, position de la cible ;paramètres:
PIsbox, largeur, hauteur de la fenêtre à la cible ;img_geo fichier de la scène
ou ;tga_geo fichier d’écriture du fichier targa
PIsangle, angle de champ de vision de l’observateur. ;view contrôle de l’affichage écran (0 ou 1)
PIsrotat, rotation de la scène autour de la ligne de visée ;tga contrôle de l’écriture du fichier targa
PIswin, définitionde l’image en pixels. ;———————————————————————————————————-
PIswincol, couleur du fond de scène (define imag_def
PIalight, définition des sources de lumière (lambda
(img_geo tga_geo view tga)
;—————————————————————————————————— ;;affichage de la vue
;VUES_DEF (newline)
;défini et exécute la construction de l’image du fichier (display “*** EXÉCUTION DE L’IMAGE..... ***”)
;volumique choisi (newline)
;—————————————————————————————————— (if
(define vues_def (= view 1)
(lambda (sol_geo img_geo tga_geo view tga) (PIshow img_geo)
;;parametres de la vue )
(PIreset) (if
(PIsobs (vector 0.4 0.3 1 0)) (= tga 1)
(PIstarget (vector 0 0 0 1)) (PItarga img_geo tga_geo)
;; au choix )
(PIsbox (vector 270 270)) (newline)
; (PIsangle (vector 30)) (display “*** FIN DE L’EXÉCUTION DE L’IMAGE..... ***”)
(PIsrotat (vector 0)) (newline)
(PIswin (vector 400 400)) )
(PIswincol (vector 1 1 1)) )
(PIalight ;———————————————————————————————————-
(vector ;COMMENTAIRES:
(vector 1 1 1 0) ;position ;———————————————————————————————————-
3
;puissance
(vector 1 1 1 1 1 1 1 1 1)
(vector 0 0 0 1 1 1 3 3 3)
)
)
;;calcul de la vue
(newline)
(display “*** EXECUTION DU FICHIER IMAGE..... ***”)
(newline)
(PIview sol_geo img_geo)
(display “*** FIN D’EXECUTION DU FICHIER IMAGE ***”)
(newline)
)
)
;————————————————————————————————

Page 25
XXX_EXE.scm (
;;élimination de triangles
Ces fonctions sont appellées à partir des fonctions “xxx_def” correspndantes à
(= (car it) 0)
la tâche à faire. (geom_exe
Dans tous les cas, elles reçoivent en paramètres les valeurs définies dans les (elimine liste_tot p_moin p_plus)
fonctions xxx_def. Cependant elles sont suffisamment différentes pour les (cdr it)
quad0 quad1 p_moin p_plus p_proj
examiner séparément.
)
)
GEOM_EXE.scm (
;;projection centrale sur la quadrique
Cette fonction exécute les modifications géométriques en fonction des paramètres reçus (= (car it) 1)
de “GEOM_DEF”. (geom_exe
C’est une fonction récursive (qui se rappelle elle-même) dont le contrôle de la répétition (sub1 liste_tot quad0 p_proj)
se fait selon les éléments restants dans la liste des traitements (it). Le rappel se fait à (cdr it)
chaque fois avec le reste de la liste jusqu’à ce qu’elle soit nulle. quad0 quad1 p_moin p_plus p_proj
à chaque étape, la liste de départ (liste_tot) est renvoyée modifiée selon le cas spécifié )
par le traitement en cours (car it) à cette étape: )
0. appelle la fonction “ELIMINE” (
1. appelle la fonction “SUB1” ;;mediannes coplanaires
10, appelle la fonction “SUB10” (= (car it) 10)
11. appelle la fonction “SUB11” (geom_exe
12. appelle la fonction “SUB12” (sub10 liste_tot)
Ces fonctions sont diverses et 10,11 &12 font appel différemment à des traitements (cdr it)
impliquant des triangles adjacents qu’il fallait d’abord repérer. Nous aurions pu les quad0 quad1 p_moin p_plus p_proj
regrouper pour une partie du traitement (la recherche des adjacences) mais nous avons )
préféré garder une autonomie de ces fonctions entre elles pour faciliter les options )
supplémentaires et tenir compte des différences dans les paramètres à envoyer. (
;;médiannes sur quadrique1
Toutes les autres fonctions font appel à un traitement triangle par triangle, sans autres (= (car it) 11)
interférences et, dans ce cas, nous les avons regroupées sous une 2ème boucle (geom_exe
(subloop2) qui identifie chaque triangle pour l’envoyer à son traitement particulier (car it). (sub11 liste_tot quad1 p_proj)
(cdr it)
quad0 quad1 p_moin p_plus p_proj
;—————————————————————————————————————
)
;GEOM_EXE
)
;enclenche la subdivision des triangles du dome
(
;par une boucle sur le nombre d’iteration
;;médianes 2 nappes quadriques 0&1
;parametres:
(= (car it) 12)
;liste_tot liste des points (format coord) et des triangles (format symb)
(geom_exe
;iteration liste des subdivision successives
(sub12 liste_tot quad1 p_proj)
;quad_x quadrique de projection
(cdr it)
;p_moin p_plus hauteurs limites d’élimination
quad0 quad1 p_moin p_plus p_proj
;p_proj centre de projection
)
;appel:
)
;subloop2 debut des boucles sur les subdivisions des triangles 1 par 1
(
;subxx traitement des triangles adjacents
(and (>= (car it) 20)(< (car it) 50))
;elimine elimination des triangles sous la hauteur de 0
(geom_exe
;retour:
(subloop2 liste_tot quad0 (car it) p_proj)
;idem liste_tot, mais mis a jour selon le traitement choisi
(cdr it)
;————————————————————————————————————-
quad0 quad1 p_moin p_plus p_proj
(define geom_exe
)
(lambda
)
(liste_tot it quad0 quad1 p_moin p_plus p_proj)
)
(if
)
(null? it)
)
liste_tot
)
(cond

Page 26
SUB1.scm SUB10.scm
Cette fonction exécute une projection des points sur une quadrique. Cette fonction assure une subdivision des triangles telle que le centre (rencontre des
On identifie d’abord la liste des points L_PT et des triangles L_TR. médianes) est joint à la fois aux sommets du triangle et au centre des triangles adjacents.
On effectue, par un “map” sur la liste des points L_PT, la transformation de tous les points Pour ce faire, on sépare la liste des points L_P0 de celle des triangles L_T0.
X par un appel à la fonction PROJECTI qui projète chaque point X sur une quadrique QUAD La fonction TRI_SEG construit une liste de segments uniques L_SEG à partir d’une liste de
à partir d’un centre de projection P_PROJ. triangles L_T0.
On reconstitue la liste globale des nouveau points et des anciens triangles L_TR. La fonction REFORME permet de transformer chaque segment de la liste L_SEG en liste
NL_TRI de triangles adjacents par ce segment (1 ou 2 triangles).
(en effet si un segment est en périférie du dôme, il n’appartient qu’à un seul triangle,
autrement il est commun à deux triangles. REFORME renvoie donc des listes de 1 ou 2
;———————————————————————————————————- triangles dont le deux premiers points identifie le segment analysé)
;SUB1 Une fonction BOUCLE récursive réduit à chaque étape cette liste NL_TRI de 1 et construit
;projete la liste de points sur une quadrique une nouvelle liste de points et de triangles NL_TOT à jour, dans laquelle L_PN est la liste
;parametres: de points et L_TN la liste de triangles.
;liste_tot liste des points et triangles
;quad quadrique de projection Dans la boucle:
;p_proj centre de projection T1 est l’élément à analyser et LONG indique le nombre de triangles de cet élément (1 ou 2).
;variables: T11_S est le premier ou le seul dont on retrouve les 3 points PA, PB, PC et on calcule le
;l_pt liste des points centre PABC par la fonction MEDIANE0.
;l_tr liste des triangles On calcule le centre PABD du 2ème triangle, s’il existe avec la fonction VERIFIE0.
;appel: La liste des nouveaux points L_PP est établie selon le nombre de triangles ainsi que la
;projecti fonction de projection d’un point sur une quadrique liste des nouveaux triangles L_TC.
;retour: Une nouvelle liste de points l_PA et de triangles L_TA est reconstruite en appelant les
;liste de points et de triangles à jour fonctions ADD_PTS & ADD_TRI pour assurer la cohérence symboles/coordonnées et
;———————————————————————————————————- éviter la redondance.
(define sub1 La fonction BOUCLE renvoie donc une nouvelle liste de points et de triangles à jour.
(lambda
(liste_tot quad p_proj)
(let
( ;———————————————————————————————————-
(l_pt (car liste_tot)) ;SUB10
(l_tr (cadr liste_tot)) ;assure la subdivision du type triacon dans le plan du triangle de base
) ;parametres:
(list ;l_tot liste de points et de triangles
(map ;l_p0 liste initiale de points
(lambda (x) ;l_t0 liste initiale de triangles
(projecti quad x p_proj) ;l_seg liste des segments des triangles
) ;nl_tri liste des triangles adjacents
l_pt) ;———————————————————————————————————-
l_tr
)
)
)
)
;———————————————————————————————————-
;COMMENTAIRES:
;———————————————————————————————————-

Page 27
(define sub10 )
(lambda )
(l_tot) )
(let* )
( )
(l_p0 (car l_tot)) )
(l_t0 (cadr l_tot)) )
(l_seg (tri_seg (l_t0)) ;———————————————————————————————————-
(nl_tri (reforme l_seg l_t0)) ;COMMENTAIRES:
) ;———————————————————————————————————-
(let boucle
(
(l_tria nl_tri)
(nl_tot (list (list)(list)))
)
(if
(null? l_tria)
nl_tot
(boucle
(cdr l_tria)
l_p0
;nouvel nl_tot
(let*
(
(l_pn (car nl_tot))
(l_tn (cadr nl_tot))
;;
(t1 (car l_tria))
(long (length t1))
(t11_s (car t1))
(pa (list-ref l_p0 (- (car t11_s) 1)))
(pb (list-ref l_p0 (- (cadr t11_s) 1)))
(pc (list-ref l_p0 (- (caddr t11_s) 1)))
(pabc (mediane0 (list pa pb pc)))
(pabd (verifie0 l_p0 t1 long pa pb))
;;
(l_pp
(if
(> long 1)
(list pa pb pabc pabd)
(list pa pb pabc)
)
)
(l_pa (add_pts l_pp l_pn))
;;
(l_tc
(if (> long 1)
(list (list pa pabc pabd)(list pb pabc pabd))
(list (list pa pabc pb))
)
)
(l_ta (add_tri l_tc l_tn l_pa (length l_pa)))
)
(list l_pa l_ta)

Page 28
SUB11.scm (let boucle
(
(l_tria nl_tri)
Cette fonction est tout à fait similaire à SUB10 sauf en ce qui concerne la projection des
(nl_tot (list (list)(list)))
centres des triangles sur la quadrique.
)
Son fonctionnement est donc similaire aux différences suivantes:
(if
La fonction MEDIANE0 est remplacée par la fonction MEDIANES qui assure en plus la
(null? l_tria)
projection sur le quadrique.
nl_tot
La fonction VERIFIE0 est remplacée par la fonction VERIFIER qui tient compte aussi de la
(boucle
projection sur la quadrique.
(cdr l_tria)
Pour tous les autres éléments se reporter à la description de SUB10.
;nouvel nl_tot
(let*
(
(l_pn (car nl_tot))
(l_tn (cadr nl_tot))
;;
(t1 (car l_tria))
(long (length t1))
(t11_s (car t1))
(pa (list-ref l_p0 (- (car t11_s) 1)))
(pb (list-ref l_p0 (- (cadr t11_s) 1)))
(pc (list-ref l_p0 (- (caddr t11_s) 1)))
(pabc (medianes (list pa pb pc) quad p_proj))
(pabd (verifier l_p0 t1 long pa pb quad p_proj))
;;
(l_pp
(if (> long 1)
(list pa pb pabc pabd)
(list pa pb pabc)
)
)
(l_pa (add_pts l_pp l_pn))
;;
(l_tc
(if (> long 1)
(list (list pa pabc pabd)(list pb pabc pabd))
(list (list pa pabc pb))
;—————————————————————————————————-
)
;SUB11
)
;assure la subdivision du type triacon en projetant les centres des
(l_ta (add_tri l_tc l_tn l_pa (length l_pa)))
;triangles sur la quadrique.
)
;paramètres:
(list l_pa l_ta)
;l_tot liste des points et triangles à traiter
)
;quad quadrique de projection
)
;p_proj centre de projection
)
;l_seg liste des segments
)
;nl_tri liste des triangles adjacents
)
;—————————————————————————————————-
)
(define sub11
)
(lambda
;—————————————————————————————————-
(l_tot quad p_proj)
;COMMENTAIRES:
(let*
;—————————————————————————————————-
(
(l_p0 (car l_tot))
(l_t0 (cadr l_tot))
(l_seg (tri_seg l_t0))
(nl_tri (reforme l_seg l_t0))
)

Page 29
SUB12.scm ;;
(l_pp
Cette fonction est similaire à SUB11 en conservant, en plus le segment initial. Ainsi (if (> long 1)
chaque segment commun à deux triangles est remplacé par un tétraèdre formé ainsi: (list pa pb pabc pabd)
les 2 sommets du segment (list pa pb pabc)
les 2 centres (rencontre des médianes) des triangles adjacents, projetés sur la quadrique. )
Chaque segment renvoie, ainsi, 4 triangles. )
(l_pa (add_pts l_pp l_pn))
;;
(l_tc
;————————————————————————————————— (if (> long 1)
;SUB12 (list (list pa pabc pabd)
;assure la subdivision du type triacon en projetant les centres des (list pb pabc pabd)
;triangles sur la quadrique mais forme une double nappe en replacant (list pa pb pabc)
;chaque segment adjacent à 2 triangles par un tétraèdre formé des 2 (list pa pb pabd)
;sommets du segment et des deux centres des triangles adjacents. )
;paramètres: (list (list pa pb pabc))
;l_tot liste des points et triangles à traiter )
;quad quadrique de projection )
;p_proj centre de projection (l_ta (add_tri l_tc l_tn l_pa (length l_pa)))
;l_seg liste des segments )
;nl_tri liste des triangles adjacents (list l_pa l_ta)
)
;————————————————————————————————— )
(define sub12 )
(lambda )
(l_tot quad p_proj) )
(let* )
( )
(l_p0 (car l_tot)) ;—————————————————————————————————-
(l_t0 (cadr l_tot)) ;COMMENTAIRES:
(l_seg (tri_seg l_t0)) ;—————————————————————————————————-
(nl_tri (reforme l_seg l_t0))
)
(let boucle
(
(l_tria nl_tri)
(nl_tot (list (list)(list)))
)
(if
(null? l_tria)
nl_tot
(boucle
(cdr l_tria)
;nouvel nl_tot
(let*
(
(l_pn (car nl_tot))
(l_tn (cadr nl_tot))
;;
(t1 (car l_tria))
(long (length t1))
(t11_s (car t1))
(pa (list-ref l_p0 (- (car t11_s) 1)))
(pb (list-ref l_p0 (- (cadr t11_s) 1)))
(pc (list-ref l_p0 (- (caddr t11_s) 1)))
(pabc (medianes (list pa pb pc) quad p_proj))
(pabd (verifier l_p0 t1 long pa pb quad p_proj))

Page 30
SUBLOOP2.scm (
(= type 22)
Cette fonction établie une boucle dans la liste de points et de triangles pour envoyer (sub22 l_p0 (car l_t) n_l quad)
chaque triangle au traitement demandé à savoir entre sub20 et sub41, ce qui regroupe tous )
les traitements qui peuvent se faire triangle par triangle. (
À chaque pas, la liste de triangles, L_T, est décrémentée de 1 et une nouvelle liste de (= type 30)
points et de triangles, NL, est construite selon le traitement demandé (TYPE). (sub30 l_p0 (car l_t) n_l)
Chaque différent traitement fait appel à une fonction spécifique comme SUB20 ou SUB32 )
avec les paramètres qu’elle requière. (
(= type 31)
(sub31 l_p0 (car l_t) n_l quad p_proj)
)
;——————————————————————————————-
(
;SUBLOOP2
(= type 32)
;boucle sur chaque triangle d’une liste de points et de triangles
(sub32 l_p0 (car l_t) n_l quad)
;et exécution du traitement demandé par la fonction appropriée.
)
;Les traitements n’impliquent qu’un seul triangle et peuvent être
(
;fait en autonome.
(= type 40)
;paramètres:
(sub40 l_p0 (car l_t) n_l)
;liste_tot (liste (liste de points)(liste de triangles))
)
;quad Quadrique de projection
(
;Variables:
(= type 41)
;type choix de subdivision
(sub41 l_p0 (car l_t) n_l quad p_proj)
;l_p0 liste des points existants
)
;l_t0 liste des triangles existants
)
;retour:
)
;Nouvelle liste_tot mise a jour selon le traitement
)
;——————————————————————————————-
)
(define subloop2
)
(lambda (liste_tot quad type p_proj)
)
(let
)
(
;———————————————————————————————-
(l_p0 (car liste_tot))
;COMMENTAIRES:
(l_t0 (cadr liste_tot))
;———————————————————————————————-
(new_list (list (list)(list)))
)
(let boucle
(
(l_t l_t0)
(n_l new_list)
)
(if
(null? l_t)
n_l
(boucle
(cdr l_t)
;n_l
(cond
(
(= type 20)
(sub20 l_p0 (car l_t) n_l)
)
(
(= type 21)
(sub21 l_p0 (car l_t) n_l quad p_proj)
)

Page 31
SUB2X.scm ;—————————————————————————————————
;SUB20
Cet ensemble de fonction assure la subdivision d’un triangle à partir du milieu de ses ;subdivise un triangle sur le milieu des arêtes ce qui renvoie
côtés, ce qui génère 3 nouveaux sommets. Ces 3 nouveaux sommets et les 3 existants ;4 nouveaux triangles par triangle initial dans le plan initial
forment un ensemble de 4 triangles. ;les nouveaux sommets au milieu des arêtes
Ainsi chaque triangle traité renvoie une liste de 4 triangles. ;Parametres:
On utilise 2 listes de points et triangles: ;old_list (liste (list de points (format coor))
OLD_LIST pour trouver l’information sur le triangle à traiter (et ceux qui restent). ; (liste de triangles (format symbole))
NEW_LIST pour ajouter la nouvelle information ;New_list idem mais reconstruit et mis à jour selon la subdivision
On utilise les fonctions ADD_PTS et ADD_TRI pour rajouter les points et les triangles sans ;quad quadrique de projection
duplication ni incohérence entre les coordonnées et les symboles. ;variable:
On utilise la fonction SGx_med pour trouver le milieu d’un segment. ;l_p vieille liste de points (format coord)
;l_t vieille liste de triangles (format symbole)
SUB20.scm ;tri triangle à traiter
Cette fonction reforme les triangles directement avec les milieux des segments. Les 4 ;p1..p6 sommets de la subdivision d’un triangle
nouveaux triangles sont donc situées dans le plan du triangle initial et sont coplanaires. ;l_pn liste à jour des points (format coord)
;l_tn liste à jour des triangles (format symbole)
SUB21.scm ;Retour:
Cette fonction projète les milieux des segments sur la quadrique à partir du centre de ;retourne une nouvelle liste de points et triangles
projection avec la fonction PROJECTI. Si les sommets initiaux étaient sur la même ;—————————————————————————————————-
quadrique tous les nouveaux sommets le sont après. (define sub20
(lambda
SUB22.scm (l_p0 tri n_l)
Cette fonction projète aussi les milieux des segments sur la quadrique mais dans un plan (let*
horizontal. (
Le centre de projection est établi au centre en x et z et à la hauteur y du point à projeter. ;;points du triangle à subdiviser
La projection est faite par la fonction PROJECTI. (p1 (list-ref l_p0 (- (list-ref tri 0) 1)))
(p2 (list-ref l_p0 (- (list-ref tri 1) 1)))
(p3 (list-ref l_p0 (- (list-ref tri 2) 1)))
;;calcul du milieu des segments
(p4 (SGx__euc (SGx__med p1 p2)))
(p5 (SGx__euc (SGx__med p2 p3)))
(p6 (SGx__euc (SGx__med p3 p1)))
;;new_list
(l_pn (car n_l))
(l_tn (cadr n_l))
;;liste de points possibles a rajouter
(l_pp (list p1 p2 p3 p4 p5 p6))
;;liste de points a jour
(l_pa (add_pts l_pp l_pn))
;;liste de triangles à rajouter
(l_tc
(list
(list p1 p4 p6)
(list p4 p2 p5)
(list p6 p5 p3)
(list p4 p5 p6)
)
)
;;liste de triangles a jour
(l_ta (add_tri l_tc l_tn l_pa (length l_pa)))
)
(list l_pa l_ta)
)
)
)
;——————————————————————————————————-

Page 32
;————————————————————————————————— ;—————————————————————————————————
;SUB21 ;SUB22
;subdivise un triangle sur le milieu des arêtes ce qui renvoie ;subdivise un triangle sur le milieu des arêtes ce qui renvoie
;4 nouveaux triangles par triangle initial dans le plan initial ;4 nouveaux triangles par triangle initial dans le plan initial
;les nouveaux sommets sont projetés sur la quadrique. ;les nouveaux sommets sont projetés horizontalement sur la quadrique.
;Paramètres: ;Paramètres:
;old_list (liste (list de points (format coor)) ;old_list (liste (list de points (format coor))
; (liste de triangles (format symbole)) ; (liste de triangles (format symbole))
;New_list idem mais reconstruit et mis à jour selon la subdivision ;New_list idem mais reconstruit et mis à jour selon la subdivision
;quad quadrique de projection ;quad quadrique de projection
;proj centre de projection ;proj centre de projection
;variables: ;variable:
;l_p vieille liste de points (format coord) ;l_p vieille liste de points (format coord)
;l_t vieille liste de triangles (format symbole) ;l_t vieille liste de triangles (format symbole)
;tri triangle à traiter ;tri triangle à traiter
;p1..p6 sommets de la subdivision d’un triangle ;p1..p6 sommets de la subdivision d’un triangle
;l_pn liste à jour des points (format coord) ;l_pn liste à jour des points (format coord)
;l_tn liste à jour des triangles (format symbole) ;l_tn liste à jour des triangles (format symbole)
;Retour: ;retourne une nouvelle liste de points et triangles ;Retour: ;retourne une nouvelle liste de points et triangles
;—————————————————————————————————; ;—————————————————————————————————-
(define sub21 (define sub22
(lambda (lambda
(l_p0 tri n_l quad proj) (l_p0 tri n_l quad)
(let* (let*
( ( ;;points du triangle à subdiviser
;;points du triangle à subdiviser (p1 (list-ref l_p0 (- (list-ref tri 0) 1)))
(p1 (list-ref l_p0 (- (list-ref tri 0) 1))) (p2 (list-ref l_p0 (- (list-ref tri 1) 1)))
(p2 (list-ref l_p0 (- (list-ref tri 1) 1))) (p3 (list-ref l_p0 (- (list-ref tri 2) 1)))
(p3 (list-ref l_p0 (- (list-ref tri 2) 1))) ;;calcul des milieux des segments
;;calcul du milieu des segments (s4 (SGx__euc (SGx__med p1 p2)))
(p4 (SGx__euc (projecti quad (SGx__med p1 p2) proj))) (p4 (SGx__euc (projecti quad s4 (vector 0 (vector-ref s4 1) 0 1))))
(p5 (SGx__euc (projecti quad (SGx__med p2 p3) proj))) (s5 (SGx__euc (SGx__med p2 p3)))
(p6 (SGx__euc (projecti quad (SGx__med p3 p1) proj))) (p5 (SGx__euc (projecti quad s5 (vector 0 (vector-ref s5 1) 0 1))))
;;new_list (s6 (SGx__euc (SGx__med p3 p1)))
(l_pn (car n_l)) (p6 (SGx__euc (projecti quad s6 (vector 0 (vector-ref s6 1) 0 1))))
(l_tn (cadr n_l)) ;;new_list
;;liste de points possibles a rajouter (l_pn (car n_l))
(l_pp (list p1 p2 p3 p4 p5 p6)) (l_tn (cadr n_l))
;;liste de points a jour ;;liste de points possibles a rajouter
(l_pa (add_pts l_pp l_pn)) (l_pp (list p1 p2 p3 p4 p5 p6))
;;liste de triangles à rajouter ;;liste de points a jour
(l_tc (l_pa (add_pts l_pp l_pn))
(list ;;liste de triangles à rajouter
(list p1 p4 p6) (l_tc
(list p4 p2 p5) (list
(list p6 p5 p3) (list p1 p4 p6)
(list p4 p5 p6) (list p4 p2 p5)
) (list p6 p5 p3)
) (list p4 p5 p6)
;;liste de triangles a jour )
(l_ta (add_tri l_tc l_tn l_pa (length l_pa))) )
) ;;liste de triangles a jour
(list l_pa l_ta) (l_ta (add_tri l_tc l_tn l_pa (length l_pa)))
) )
) (list l_pa l_ta)
) )
;—————————————————————————————————- ))
;—————————————————————————————————-
Page 33
SUB3X.scm ;—————————————————————————————————-
(define sub30
(lambda
Cet ensemble de fonction assurent une subdivision d’un triangle en subdivisant chaque
(l_p0 tri n_l)
arête en 3 parties égales.
(let*
Cette subdivision rajoute 9 nouveaux sommets et forme un hexagone. On trouve ensuite le
(
centre de cet hexagone comme 10ème nouveau sommet.
;;points du triangle à subdiviser
L’ensemble de ces nouveaux points forment 9 nouveaux triangles auxquels il faut rajouter
(p1 (list-ref l_p0 (- (list-ref tri 0) 1)))
les 3 autres formés par l’hexagone et les sommets existants du triangle.
(p2 (list-ref l_p0 (- (list-ref tri 1) 1)))
Cette série de fonction travaille comme la série SUB2X à la différence de la subdivision
(p3 (list-ref l_p0 (- (list-ref tri 2) 1)))
faite.
(p4 (SGx__euc (SGx__sub (vector 2 1) p1 p2)))
Pour diviser en 3 parties égales, on utilise la fonction SGx_sub qui attend un vecteur de
(p5 (SGx__euc (SGx__sub (vector 1 2) p1 p2)))
proportion entre deux points soit 2 pour 1 ou 1 pour 2 pour avoir le 1/3 ou les 2/3.
(p6 (SGx__euc (SGx__sub (vector 2 1) p2 p3)))
(p7 (SGx__euc (SGx__sub (vector 1 2) p2 p3)))
SUB30.scm (p8 (SGx__euc (SGx__sub (vector 2 1) p3 p1)))
Cette fonction subdivise les arêtes du triangle initial en 3 parties égales et reforme les 9 (p9 (SGx__euc (SGx__sub (vector 1 2) p3 p1)))
nouveaux triangles dans le plan du triangle initial. (p10(SGx__euc (SGx__med p5 p8)))
;;new_list
SUB31.scm (l_pn (car n_l))
Cette fonction projette les nouveaux points obtenus, sur les arêtes et au centre, sur une (l_tn (cadr n_l))
quadrique à partir d’un centre de projection. Elle utilise la fonction PROJECTI ;;liste de points possibles a rajouter
(l_pp (list p1 p2 p3 p4 p5 p6 p7 p8 p9 p10))
SUB32.scm ;;liste de points a jour
Cette fonction projette aussi les nouveaux points obtenus sur une quadrique mais dans un (l_pa (add_pts l_pp l_pn))
plan horizontal. ;;liste de triangles à rajouter
Chaque point est projeté à partir d’un centre de projection dont x et z sont à l’origine et y à (l_tc
la hauteur du point à projeter. La projection se fait par la fonction PROJECTI (list
(list p1 p4 p9 )
(list p4 p5 p10)
(list p4 p10 p9 )
(list p9 p10 p8 )
(list p5 p2 p6 )
;—————————————————————————————————- (list p5 p6 p10)
;SUB30 (list p10 p6 p7 )
;subdivise un triangle en subdivisant ses arêtes en 3 parties égales (list p8 p10 p7 )
;pour former 9 nouveaux triangles par triangle initial dans le plan (list p8 p7 p3 )
;du triangle initial )
;les nouveaux sommets sont au 1/3 et au 2/3 des arêtes )
;Parametres: ;;liste de triangles a jour
;l_p0 (list de points (format coor) (l_ta (add_tri l_tc l_tn l_pa (length l_pa)))
;tri triangle (format symbole) )
;n_l idem mais reconstruit et mis à jour selon la subdivision (list l_pa l_ta)
;variable: )
;l_p vieille liste de points (format coord) )
;l_t vieille liste de triangles (format symbole) )
;tri triangle à traiter ;—————————————————————————————————
;p1..p10 sommets de la subdivision d’un triangle ;COMMENTAIRES:
;l_pa liste à jour des points (format coord) ;—————————————————————————————————
;l_ta liste à jour des triangles (format symbole)
;Retour:
;retourne une nouvelle liste de points et triangles
;—————————————————————————————————-

Page 34
;—————————————————————————————————- ;;liste de triangles à jour
;SUB31 (l_ta (add_tri l_tc l_tn l_pa (length l_pa)))
;subdivise un triangle en subdivisant ses arêtes en 3 parties égales )
;pour former 9 nouveaux triangles par triangle initial. (list l_pa l_ta)
;les nouveaux sommets sont au 1/3 et au 2/3 des arêtes et sont proje )
;tés sur une quadrique à partir d’un centre de projection )
;Parametres: )
;l_p0 (list de points (format coor) ;—————————————————————————————————-
;tri triangle (format symbole) ;COMMENTAIRES:
;quad Quadrique de projection ;—————————————————————————————————-
;proj centre de projection
;n_l idem mais reconstruit et mis à jour selon la subdivision
;variable:
;l_p vieille liste de points (format coord)
;l_t vieille liste de triangles (format symbole)
;p1..p10 sommets de la subdivision d’un triangle
;l_pa liste à jour des points (format coord)
;l_ta liste à jour des triangles (format symbole)
;Retour:
;retourne une nouvelle liste de points et triangles
;—————————————————————————————————-
(define sub31
(lambda
(l_p0 tri n_l quad proj)
(let*
(
;;points du triangle subdivisé
(p1 (list-ref l_p0 (- (list-ref tri 0) 1)))
(p2 (list-ref l_p0 (- (list-ref tri 1) 1)))
(p3 (list-ref l_p0 (- (list-ref tri 2) 1)))
(p4 (SGx__euc (projecti quad (SGx__sub (vector 2 1) p1 p2) proj)))
(p5 (SGx__euc (projecti quad (SGx__sub (vector 1 2) p1 p2) proj)))
(p6 (SGx__euc (projecti quad (SGx__sub (vector 2 1) p2 p3) proj)))
(p7 (SGx__euc (projecti quad (SGx__sub (vector 1 2) p2 p3) proj)))
(p8 (SGx__euc (projecti quad (SGx__sub (vector 2 1) p3 p1) proj)))
(p9 (SGx__euc (projecti quad (SGx__sub (vector 1 2) p3 p1) proj)))
(p10(SGx__euc (projecti quad (SGx__med p5 p8) proj)))
;;new_list
(l_pn (car n_l))
(l_tn (cadr n_l))
;;liste de points possibles a rajouter
(l_pp (list p1 p2 p3 p4 p5 p6 p7 p8 p9 p10))
;;liste de points a jour
(l_pa (add_pts l_pp l_pn))
;;liste de triangles à rajouter
(l_tc
(list
(list p1 p4 p9 )
(list p4 p5 p10)
(list p4 p10 p9 )
(list p9 p10 p8 )
(list p5 p2 p6 )
(list p5 p6 p10)
(list p10 p6 p7 )
(list p8 p10 p7 )
(list p8 p7 p3 )
)
)
Page 35
;—————————————————————————————————- ;—————————————————————————————————-
;SUB32 (define sub32
;subdivise un triangle en subdivisant ses arêtes en 3 parties égales (lambda
;pour former 9 nouveaux triangles par triangle initial. (l_p0 tri n_l quad)
;les nouveaux sommets sont au 1/3 et au 2/3 des arêtes et sont proje (let*
;tés sur une quadrique horizontalement. (
;Parametres: ;;points du triangle subdivise
;l_p0 (list de points (format coor) (p1 (list-ref l_p0 (- (list-ref tri 0) 1)))
;tri triangle (format symbole) (p2 (list-ref l_p0 (- (list-ref tri 1) 1)))
;quad Quadrique de projection (p3 (list-ref l_p0 (- (list-ref tri 2) 1)))
;n_l idem mais reconstruit et mis à jour selon la subdivision (s4 (SGx__euc (SGx__sub (vector 2 1) p1 p2)))
;variable: (p4 (SGx__euc (projecti quad s4 (vector 0 (vector-ref s4 1) 0 1))))
;l_p vieille liste de points (format coord) (s5 (SGx__euc (SGx__sub (vector 1 2) p1 p2)))
;l_t vieille liste de triangles (format symbole) (p5 (SGx__euc (projecti quad s5 (vector 0 (vector-ref s5 1) 0 1))))
;p1..p10 sommets de la subdivision d’un triangle (s6 (SGx__euc (SGx__sub (vector 2 1) p2 p3)))
;l_pa liste à jour des points (format coord) (p6 (SGx__euc (projecti quad s6 (vector 0 (vector-ref s6 1) 0 1))))
;l_ta liste à jour des triangles (format symbole) (s7 (SGx__euc (SGx__sub (vector 1 2) p2 p3)))
;Retour: (p7 (SGx__euc (projecti quad s7 (vector 0 (vector-ref s7 1) 0 1))))
;retourne une nouvelle liste de points et triangles (s8 (SGx__euc (SGx__sub (vector 2 1) p3 p1)))
;—————————————————————————————————- (p8 (SGx__euc (projecti quad s8 (vector 0 (vector-ref s8 1) 0 1))))
(s9 (SGx__euc (SGx__sub (vector 1 2) p3 p1)))
(p9 (SGx__euc (projecti quad s9 (vector 0 (vector-ref s9 1) 0 1))))
(s10(SGx__euc (SGx__med s5 s8)))
(p10(SGx__euc (projecti quad s10 (vector 0 (vector-ref s10 1) 0 1))))
;;new_list
(l_pn (car n_l))
(l_tn (cadr n_l))
;;liste de points possibles a rajouter
(l_pp (list p1 p2 p3 p4 p5 p6 p7 p8 p9 p10))
;;liste de points a jour
(l_pa (add_pts l_pp l_pn))
;;liste de triangles à rajouter
(l_tc
(list
(list p1 p4 p9 )
(list p4 p5 p10)
(list p4 p10 p9 )
(list p9 p10 p8 )
(list p5 p2 p6 )
(list p5 p6 p10)
(list p10 p6 p7 )
(list p8 p10 p7 )
(list p8 p7 p3 )
)
)
;;liste de triangles à jour
(l_ta (add_tri l_tc l_tn l_pa (length l_pa)))
)
(list l_pa l_ta)
)
)
)

Page 36
SUB4X.scm ;——————————————————————————————————
(define sub40
cet ensemble de fonction subdivise un triangle à partir du point de rencontre des (lambda
médianes qui joint aux trois sommets existants détermine 3 triangles. Chaque triangle est (l_p0 tri n_l)
ainsi remplacé par 3 nouveaux triangles. (let*
(
;;points du triangle subdivise
SUB40.scm
(p1 (list-ref l_p0 (- (list-ref tri 0) 1)))
Cette fonction assure que le point de rencontre des médianes est coplanaire avec le
(p2 (list-ref l_p0 (- (list-ref tri 1) 1)))
triangle initial.
(p3 (list-ref l_p0 (- (list-ref tri 2) 1)))
(p4 (mediane0 (list p1 p2 p3)))
SUB41.scm ;;new_list
Cette fonction projète le point de rencontre des médianes sur une quadrique à partir d’un (l_pn (car n_l))
centre de projection. (l_tn (cadr n_l))
;;liste de points possibles a rajouter
;—————————————————————————————————— (l_pp (list p1 p2 p3 p4))
;SUB40 ;;liste de points a jour
;subdivise un triangle en formant 3 triangles à partir des sommets (l_pa (add_pts l_pp l_pn))
;existants et du point de rencontre des médianes comme nouveau point. ;;liste de triangles à rajouter
;Le triangle initial est remplacé par 3 nouveaux triangles (l_tc
;le nouveau sommet est coplanaire avec les 3 autres. (list
;Paramètres: (list p1 p2 p4)
;l_p0 ancienne liste de points (format coor) (list p4 p2 p3)
;n_l nouvelle liste de points et de triangles (list p4 p3 p1)
;tri triangle à traiter )
;variable: )
;l_p vieille liste de points (format coord) ;;liste de triangles a jour
;l_t vieille liste de triangles (format symbole) (l_ta (add_tri l_tc l_tn l_pa (length l_pa)))
;p1..p4 sommets de la subdivision d’un triangle )
;l_pn liste à jour des points (format coord) (list l_pa l_ta)
;l_tn liste à jour des triangles (format symbole) )
;Retour: )
;retourne une nouvelle liste de points et triangles
;—————————————————————————————————— )
;——————————————————————————————————
;COMMENTAIRES:
;——————————————————————————————————

Page 37
;—————————————————————————————————— TRI_SEG.scm
;SUB41
;subdivise un triangle en formant 3 triangles à partir des sommets Cette fonction transforme une liste de triangles LISTE_TRI (formats symbolique) en liste
;existants et du point de rencontre des médianes comme nouveau point. d’arêtes uniques LISTE_SEG (format symbolique).
;Le triangle initial est remplacé par 3 nouveaux triangles Elle génère une fonction récursive BOUCLE qui, à chaque pas, décrémente la liste des
;le nouveau sommet est projeté sur une quadrique. triangles L_T, identifie un triangle T, le transforme en liste de segments L pour fin d’ajout à
;Paramètres: la liste des segments par la fonction ADD_SEG.
;l_p0 ancienne liste de points (format coor)
;n_l nouvelle liste de points et de triangles
;tri triangle à traiter
;————————————————————————————————————
;variable:
;TRI_SEG
;l_p vieille liste de points (format coord)
;transforme une liste de triangles en liste de segments uniques
;l_t vieille liste de triangles (format symbole)
;paramètres:
;p1..p4 sommets de la subdivision d’un triangle
;liste_tri liste de triangles
;l_pn liste à jour des points (format coord)
;liste_seg liste de segments
;l_tn liste à jour des triangles (format symbole)
;appel:
;Retour:
;add_seg fonction qui ajoute à une liste de segments ceux d’une autre liste
;retourne une nouvelle liste de points et triangles
; de segment qui ne sont pas déjà dans la première.
;—————————————————————————————-
;retour:
(define sub41
;liste de segments uniques
(lambda
;————————————————————————————————————
(l_p0 tri n_l quad proj)
(define tri_seg
(let*
(lambda (liste_tri)
(
(let boucle
;;points du triangle subdivise
(
(p1 (list-ref l_p0 (- (list-ref tri 0) 1)))
(liste_seg (list))
(p2 (list-ref l_p0 (- (list-ref tri 1) 1)))
(l_t liste_tri)
(p3 (list-ref l_p0 (- (list-ref tri 2) 1)))
)
(p4 (medianes (list p1 p2 p3) quad proj))
(if
;;new_list
(null? l_t)
(l_pn (car n_l))
liste_seg
(l_tn (cadr n_l))
(let*
;;liste de points possibles a rajouter
(
(l_pp (list p1 p2 p3 p4))
(t (car l_t))
;;liste de points a jour
(a (list-ref t 0))
(l_pa (add_pts l_pp l_pn))
(b (list-ref t 1))
;;liste de triangles à rajouter
(c (list-ref t 2))
(l_tc
(l (list (list a b)(list b c)(list c a)))
(list
)
(list p1 p2 p4)
(boucle (add_seg liste_seg l)(cdr l_t))
(list p4 p2 p3)
)
(list p4 p3 p1)
)
)
)
)
)
;;liste de triangles a jour
)
(l_ta (add_tri l_tc l_tn l_pa (length l_pa)))
;—————————————————————————————————————
)
;COMMENTAIRES:
(list l_pa l_ta)
;—————————————————————————————————————
)
)
)
;——————————————————————————————————
;COMMENTAIRES:
;——————————————————————————————————

Page 38
ADD_SEG.scm ADD_PTS.scm

Cette fonction ajoute une liste de nouveaux segments LS à une liste existante de segments Cette fonction ajoute une liste de points nouveau à une liste de points existants en
LISTE_SEG en évitant la redondance, c’est à dire seulement s’ils n’existent pas déjà dans s’assurant de ne pas faire de duplication. Elle rajoute les points que s’il n’existent pas déjà
la liste existante. Elle retourne la liste de segments LISTE_SEG à jour. dans la liste.
La vérification de l’existance d’un segment se fait par la fonction MEMBER. mais il faut C’est une fonction récursive ou à chaque étape, la liste de points à rajouter L_PP diminue
vérifier pour chaque segment les 2 formats possibles (ab) et (ba). de 1 jusqu’à ce qu’elle soit nulle et la liste de points existants L_PN augmente
C’est aussi une fonction récursive qui décrémente la liste des nouveaux segments à éventuellement.
étudier et renvoie, à chaque pas, la liste existante mise à jour. Si le point étudié (CAR L_PP) n’existe pas dans la liste (fonction MEMBER) il y est ajouté
Lorsque le segment existe déjà, elle renvoie la liste existante sans changements. (APPEND) autrement la liste existante L_PN est retournée.

;——————————————————————————————————— ;————————————————————————————————-
;ADD_SEG ;ADD_PTS
;fonction qui ajoute à une 1ère liste de segments les éléments d’une autre liste ;ajoute éléments d’une liste de points a une liste existante
;non contenus dans la première. ;s’ils n’existent pas encore dans cette liste.
;paramètres: ;Paramètres:
;liste_seg 1ère liste ;l_pp liste de points a rajouter s’il y a lieu
;ls 2ème liste ;l_pn liste de points existants
;retour: ;retour:
;1ère liste à jour ;liste de points existants augmentée de nouveaux éléments
;——————————————————————————————————— ;————————————————————————————————-
(define add_seg (define add_pts
(lambda (lambda
(liste_seg ls) (l_pp l_pn)
(if (if
(null? ls) (null? l_pp)
liste_seg l_pn
(let* (add_pts
( (cdr l_pp)
(s (car ls)) (if
(a (car s)) (= 0 (length (member (car l_pp) l_pn)))
(b (cadr s)) (append l_pn (list (car l_pp)))
) l_pn
(if )
(and )
(= 0 (length (member (list a b) liste_seg))) )
(= 0 (length (member (list b a) liste_seg))) )
) )
(add_seg (cons s liste_seg)(cdr ls)) ;———————————————————————————————————
(add_seg liste_seg (cdr ls)) ;COMMENTAIRES:
) ;———————————————————————————————————
)
)
)
)
;———————————————————————————————————
;COMMENTAIRES:
;———————————————————————————————————

Page 39
ADD_TRI.scm MÉDIANEx.scm
Cette fonction ajoute une liste de triangles sous forme de coordonnées à une liste Ces deux fonctions calculent le point de rencontre des médianes d’un triangle. px & py
existante de triangles sous forme de symboles en se servant d’une liste de points sous sont les milieux des segments a-b & a-c d’un triangle abc.
forme de coordonnées qui comprend celles des triangles à rajouter. Le point renvoyé est l’intersection des segments b-py et c-px.
C’est une fonction récursive où, à chaque étape, la liste des triangles à rajouter diminue de La fonction MEDIANE0.scm conserve le point dans le plan du triangle alors que MEDIANES
1 est celle des triangles existants augmente de 1. le projète sur une quadrique.
La traduction de coordonnées à symbole se fait par la fonction COOTOSYM qui recherche
la position du point dans la liste de point et la retient comme symbole.
LONG sert à stopper la recherche du point dans la liste.
;—————————————————————————————————-
;MEDIANE0
;calcule le point de rencontre des médianes d’un triangle
;——————————————————————————————————————- ;paramètres:
;ADD_TRI ;abc liste des 3 points (coor) du triangle
;ajoute une liste de triangles (liste de 3 coordonnées de points)à une liste ;retour:
;existante de triangles (liste de 3 symboles correspondant à des positions ;point de rencontre des médianes
;de points dans une liste de points) ;—————————————————————————————————-
;paramètres: (define mediane0
;l_tc liste de triangles (3 points format coordonnées) (lambda
;l_tn liste existante de triangles (3 points format symbole) (abc)
;l_pa liste de points (format coordonnées) (let*
;long longueur de l_pa (
;appel: (pa (car abc))
;cootosym transforme le format d’une liste de points de coord a symbolique (pb (cadr abc))
;par rapport à une liste de points ou ils existent. (pc (caddr abc))
;retour: (px (SGx__euc (SGx__med pa pb)))
;liste de triangles (3 points format symbole) (py (SGx__euc (SGx__med pa pc)))
;——————————————————————————————————————- )
(define add_tri (SGx__euc(SGx___4x pb py pc px))
(lambda )
(l_tc l_tn l_pa long) )
(if )
(null? l_tc) ;————————————————————————————————
l_tn ;MEDIANES
(add_tri ;calcule le point de rencontre des médianes d’un triangle
(cdr l_tc) ;et le projette sur la quadrique
(append ;paramètres:
l_tn ;abc liste des 3 points (coor) du triangle
(list (cootosym (car l_tc) l_pa long)) ;quad vecteurs de la quadrique
) ;————————————————————————————————
l_pa (define medianes
long (lambda
) (abc quad proj)
) (let*
) (
) (pa (car abc))
;—————————————————————————————————————— (pb (cadr abc))
;COMMENTAIRES: (pc (caddr abc))
;—————————————————————————————————————— (px (SGx__euc (SGx__med pa pb)))
(py (SGx__euc (SGx__med pa pc)))
)
(SGx__euc (projecti quad (SGx___4x pb py pc px) proj))
)
)
)
;————————————————————————————————

Page 40
PROJECTI.scm REFORME.scm
Cette fonction assure la projection d’un point PT sur une quadrique QUAD à partir d’un Cette fonction assure la recherche des triangles qui partagent une arête. C’est une
centre de projection PROJ. On cherche le point de percé de la droite proj->pt sur la fonction récursive qui examine une liste de segments L_SEG par rapport à une liste de
quadrique (SGqdrray) qui renvoie 2 points. Il faut chercher celui qui est dans le sens proj- triangles L_TRI. Les deux sont en format symbolique.
>pt. Pour cela on projète pt à l’infini dans la direction proj->pt et on mesure l’angle entre Elle assure la boucle sur la liste des segments alors que la fonction ADJACENT fait le
cette droite et les deux droites possibles, proj->px et proj->py. Si l’angle est nul, c’est le travail.
bon point si non c’est le point opposé. Elle recherche pour chacun les triangles qui ont ce segment. Elle retourne une liste de
résultat qui peuvent être une liste de 2 triangles ou un seul si le segment est à la base du
;———————————————————————————————————- dôme (sans voisin).
;PROJECTI
;———————————————————————————————————
;projette un point sur une quadrique à partir d’un centre de projection
;REFORME
;paramètres:
;reforme une liste de paires de triangles qui partagent la même arête
;quad quadrique
;les 2 premiers points des triangles sont l’arête commune
;pt point (format coordonnées)
;lorsque l’arête n’est pas partagée la liste ne comprend qu’un triangle
;proj centre de projection
;et les 2 premiers points forment l’arête sans adjacence
;retour:
;paramètres:
;point projeté
;l_seg liste des segments des triangles (format symbole)
;———————————————————————————————————-
;l_tri liste des triangles originaux (format symbole)
(define projecti
;retour:
(lambda (quad pt proj)
;liste de liste de 2 ou 1 triangle (format symbole)
(let*
;———————————————————————————————————
(
(define reforme
(p0 (SGvecpos proj))
(lambda
(pa (SGvecpos pt))
(l_seg l_tri)
(pdouble (SGqdrray p0 pa quad))
(let boucle2
(px (SGvecpos (vector-ref pdouble 0)))
(
(py (SGvecpos (vector-ref pdouble 1)))
(l_sx l_seg)
(pinf (SGvct__y (SGy__coo p0 pa)))
(l_tx l_tri)
(cos_x (SGcos_2y (SGy__coo p0 pinf)(SGy__coo p0 px)))
(l_fin (list))
(cos_y (SGcos_2y (SGy__coo p0 pinf)(SGy__coo p0 py)))
)
)
(if
(if (> cos_x 0)
(null? l_sx)
(SGx__euc px)
l_fin
(SGx__euc py)
(boucle2
)
(cdr l_sx)
)
l_tx
)
;nouvel l_fin
)
(let
;——————————————————————————————————-
(
;COMMENTAIRES:
(seg (car l_sx))
;l’intersection de la droite po pa avec la quadrique retourne 2 points
)
;(p_double) qui séparés donnent px et py.
(cons (adjacent seg l_tx) l_fin)
;pour choisir le bon, on projette à l’infini pa dans la direction p0->pa
)
;pour obtenir pinf.
)
;on évalue le cosinus de l’angle entre p0 px et p0 pinf. s’il est
)
;égal à 1 l’angle est nul et px est l’intersection de la droite avec
)
;la quadrique dans la direction p0->pa et non la direction opposée.
)
;Autrement il faut retenir py.
)
;prendre le point dont le cos = 1 et non -1. Pour éviter les imprécisions
;———————————————————————————————————
;on test avec >0 pour 1 et <0 pour -1.
;COMMENTAIRES:
;——————————————————————————————————-
;———————————————————————————————————

Page 41
ADJACENT.scm VOISIN.scm

En fonction d’une liste de triangles L_TRI, elle cherche ceux qui ont un segment donné Cette fonction détermine l’appartenance d’un segment (seg) à un triangle (tri).
SEG. On doit d’abord identifier les deux sommets a&b du segment et tester leur existence dans
Elle assure la boucle de recherche sur la liste des triangles (L_TX). La fonction VOISIN fait le triangle (MEMBER) si les deux existent on recherche le 3ème avec la fonction
l’analyse de 1 segment pour 1 triangle. TRIORDRE pour reformer le triangle en s’assurant que les deux premiers termes sont ceux
Noter qu’il peut y avoir 1 ou 2 triangles qui répondent au test. Il faut donc parcourir toute la du segment analysé.
liste. En effet, ainsi une liste de deux triangles adjacents le seront par les deux premiers points
dans leur description ce qui facilite l’utilisation de cette information.
;—————————————————————————————————-
;————————————————————————————————-
;ADJACENT
;VOISIN
;recherche a partir d’un segment les 2 triangles qui l’ont en commun
;dans une liste de triangle ou le triangle limite sans voisin ;teste l’appartenance d’un segment a un triangle (format symbole)
;et renvoi le triangle dont les 2 premiers points sont ceux du
;la fonction assure la boucle de vérification du segment avec chacun
;des triangles de la liste ;segment ou une liste vide
;Paramètres:
;Paramètres:
;seg segment (liste de 2 points)
;seg segment (liste de 2 points format symbole)
;tri triangle (liste de 3 points)
;l_tri liste de triangles (liste de 3 points format symbole)
;Appel:
;retour:
;liste de triangles ;triordre recherche le point d’un triangle différent de ceux du segment
;retour:
;—————————————————————————————————-
(define adjacent ;liste de 3 points ou nulle
;————————————————————————————————
(lambda
(define voisin
(seg l_tri)
(let boucle1 (lambda
(seg tri)
(
(sg seg) (let
(
(l_tx l_tri)
(a (car seg))
(l_fin (list))
(b (cadr seg))
)
)
(if
(null? l_tx) (if
(and (member a tri)
l_fin
(boucle1 (member b tri)
)
sg
;;triangle ordonne
(cdr l_tx)
;;nouvel l_fin (list a b (triordre a b tri))
(list)
(let
( )
)
(result (voisin sg (car l_tx)))
)
)
)
(if
;—————————————————————————————————
(null? result)
l_fin ;COMMENTAIRES:
;afin de reconnaitre facilement plus tard quel était le segment du
(append (list result) l_fin)
) ;triangle trouve était étudié il est écrit en premier dans la liste.
;La fonction triordre trouve le 3ème sommet et l’écrit en dernier.
)
;—————————————————————————————————
)
)
)
)
)
;———————————————————————————————————
;COMMENTAIRES:
;———————————————————————————————————

Page 42
TRIORDRE.scm
À partir de 2 points appartenant à un triangle et la liste des 3 sommets de ce triangle, la
fonction recherche et renvoie le 3ème sommet.

;——————————————————————————————————- ;———————————————————————————
;TRIORDRE ;VERIFIE0
;recherche le point d’un triangle qui n’appartient pas a un segment de ;Calcule le point de rencontre des médianes du 2ème triangle
;celui-ci. ;s’il existe dans la liste.
;Paramètre ;paramètre:
;a & b 2 points du triangle (format symbole) ;l_p0 liste de points format coordonnées
;tria triangle (liste de 3 points format symbole) ;t1 liste de 1 ou 2 triangles
;retour: ;long longueur de la liste de triangles
;le point de tria different de a & b ;pa & pb segment commun aux 2 éventuels triangles (format
;——————————————————————————————————- ; coordonnées
(define triordre ;retour: point de rencontre des médianes dans le plan du
(lambda ; triangle
(a b tria) ;———————————————————————————
(if (define verifie0
(or (lambda
(= a (car tria)) (l_p0 t1 long pa pb)
(= b (car tria)) (if
) (> long 1)
(triordre a b (cdr tria)) (mediane0
(car tria) (list
) pa pb
) (list-ref l_p0 (- (caddr (cadr t1)) 1))
) )
;——————————————————————————————————- )
;Commentaires: (list)
;la fonction est récursive et teste l’équivalence de chaque point )
;du triangle avec les deux points donnes )
;——————————————————————————————————- )
;———————————————————————————
;COMMENTAIRES:
;———————————————————————————

Page 43
ELIMINE.scm (let boucle
(
Cette fonction effectue l’élimination des triangles qui sont totalement en dessous et au (l_t l_t0)
dessus d’une hauteur de référence. (n_l new_list)
Elle sépare d’abord la liste des sommets et celle es triangles à traiter (L_P0 et l_TO) et )
initialise une nouvelle liste nulle NEW_LIST. (if
Elle définie une fonction récursive (BOUCLE) qui se rappelle avec une liste de triangle (null? l_t)
décroissante tant qu’elle n’est pas nulle (L_T) et une nouvelle liste (N_L) qui s’accroit n_l
lorsque le triangle étudié (TRI) doit être conservé. (boucle
À chaque incrément: (cdr l_t)
On récupère les corrdonnées (x,y,z,t) des sommets (P1, P2, P3) du triangle étudié, ;;new_list
identifiés symboliquement par leur position dans la liste des points L_P0. (let*
On identifie, dans la nouvelle liste en construction celle des points L_PN et celle des (
triangles L_TN ainsi que la liste de points L_PP et de triangles L_TC qui sont susceptibles (tri (car l_t))
d’être retenus. ;;points du triangle a evaluer
On reconstruit les listes de points (sous forme de coordonnées) L_PA et de triangles (sous (p1 (list-ref l_p0 (- (list-ref tri 0) 1)))
forme symbolique) L_TA dans le cas ou le triangle est conservé. (p2 (list-ref l_p0 (- (list-ref tri 1) 1)))
On teste la validité du triangle: (p3 (list-ref l_p0 (- (list-ref tri 2) 1)))
Si les 3 sommets sont audessus de la hauteur minimum ou en dessous de la hauteur ;;new_list
maximum, la nouvelle liste est retenue, sans cela l’ancienne (N_L) est conservée. (l_pn (car n_l))
(l_tn (cadr n_l))
Note: ;;points possibles
Les fonctions “ADD_PTS & ADD_TRI” assurent: (l_pp (list p1 p2 p3))
Une cohérence complète entre la position des points dans la liste des points et leur ;;points à rajouter
symbole utilisé dans la liste des triangles. (l_pa (add_pts l_pp l_pn))
L’abscence de redondance dans les listes de points et de triangles. ;;triangle possible
(l_tc (list (list p1 p2 p3)))
;;triangle a rajouter
;————————————————————————————————————- (l_ta (add_tri l_tc l_tn l_pa (length l_pa)))
;ELIMINE )
;élimine les triangles qui sont complètement (if
;soit en dessous de p_moin soit au dessus de p_plus (and
;Paramètres: (or
;old_list (liste (list de points (format coor)) (> (vector-ref p1 1) (+ p_moin 0.1))
; (liste de triangles (format symbole)) (> (vector-ref p2 1) (+ p_moin 0.1))
;p_moin hauteur de référence (> (vector-ref p3 1) (+ p_moin 0.1))
;p_plus hauteur de référence )
;variables: (or
;New_list liste reconstruite et mise à jour selon la hauteur (< (vector-ref p1 1) (- p_plus 0.1))
;l_p0 vieille liste de points (format coord) (< (vector-ref p2 1) (- p_plus 0.1))
;l_t0 vieille liste de triangles (format symbole) (< (vector-ref p3 1) (- p_plus 0.1))
;tri premier triangle de la liste de triangles existants )
;p1,p2,p3 sommets d’un triangle )
;l_pn liste à jour des points (format coord) (list l_pa l_ta)
;l_tn liste à jour des triangles (format symbole) n_l
;Retour: )
;retourne une nouvelle liste de points et triangles )
;———————————————————————————————————— )
(define elimine )
(lambda (old_list p_moin p_plus) )
(let )
( )
(l_p0 (car old_list)) )
(l_t0 (cadr old_list)) ;————————————————————————————————————-
(new_list (list (list)(list))) ;COMMENTAIRES:
) ;————————————————————————————————————-

Page 44
;—————————————————————————————— ;————————————————————————————————
;VERIFIER ;SYMTOCOO
;Calcule le point de rencontre des médianes du 2ème triangle ;transforme une liste de point format symbolique en liste de points
;s’il existe dans la liste. ;format coordonnées.
;paramètre: ;paramètres:
;l_p0 liste de points format coordonnées ;liste_sym liste de points format symbolique
;t1 liste de 1 ou 2 triangles ;liste_coo liste de tous les points format coordonnées
;long longueur de la liste de triangles ;retour:
;pa & pb segment commun aux 2 éventuels triangles (format ;liste_sym en format coordonnées
; coordonnées ;————————————————————————————————
;quad_ref quadrique de projection (define symtocoo
;proj centre de projection (lambda (liste_sym liste_coo)
;retour: point de rencontre des médianes du triangle projeté (map
; sur la quadrique. (lambda (x)
;—————————————————————————————— (list-ref liste_coo (- x 1))
(define verifier )
(lambda liste_sym)
(l_p0 t1 long pa pb quad_ref proj) )
(if )
(> long 1) ;———————————————————————————————-
(medianes ;COMMENTAIRES:
(list ;———————————————————————————————-
pa pb
(list-ref l_p0 (- (caddr (cadr t1)) 1))
)
quad_ref
proj ;——————————————————————————————————-
) ;COOTOSYM
(list) ;transforme une liste de points sous forme de coordonnées (tc)
) ;en liste de positions de ces points dans une liste de points l_pa
) ;qui les contient. Elle génère donc le format symbolique d’une liste
) ;de points.
;———————————————————————————- ;paramètres:
;COMMENTAIRES: ;tc liste de points sous forme de coordonnées (triangle)
;———————————————————————————- ;l_pa liste de l’ensemble des points du dôme sous forme de coordonnées
;long longueur de l_pa
;retour:
;liste des positions des points de tc dans l_pa
;——————————————————————————————————-
(define cootosym
(lambda
(tc l_pa long)
(map
(lambda (x)
(+ (- long (length (member x l_pa))) 1)
)
tc)
)
)
;——————————————————————————————————-
;COMMENTAIRES:
;——————————————————————————————————-

Page 45
VOL_LOAD.scm ;———————————————————————————————————-
Cette fonction charge toutes les fonctions nécessaires au traitement volumique. (define min_max
(lambda
(liste_point)
(let*
;———————————————————————————————————-
;VOL_LOAD (
(lx
;charge les fonctions de traitement volumique de la géométrie
;d’un dôme géodésique (map
(lambda (x)
;———————————————————————————————————-
(vector-ref x 0)
(define vol_load
)
(lambda ()
liste_point)
(begin
(load “panneau1.scm”) )
(ly
(load “panneau0.scm”)
(load “arete.scm”) (map
(lambda (x)
(load “sommets.scm”)
(vector-ref x 1)
(load “unisegme.scm”)
(load “trisegme.scm”) )
liste_point)
(load “ellipsoi.scm”)
(load “cone.scm”) )
(lz
(load “parabolo.scm”)
(map
(load “volu_exe.scm”)
(lambda (x)
(load “min_max.scm”)
(vector-ref x 2)
)
) )
liste_point)
)
;——————————————————————————————————— )
(x_min (apply min lx))
;COMMENTAIRES:
(y_min (apply min ly))
;———————————————————————————————————
(z_min (apply min lz))
(x_max (apply max lx))
MIN_MAX.scm (y_max (apply max ly))
Cette fonction calcule la quadrique qui englobe un nuage de points donné sous forme de (z_max (apply max lz))
(x_cen (/ (+ x_min x_max) 2))
liste: (y_cen (/ (+ y_min y_max) 2))
Un “map” sur la liste permet d’obtenir 3 listes séparées des X,Y et Z des points de départ (z_cen (/ (+ z_min z_max) 2))
(LX, LY et LZ). )
Un “(apply min .. sur chaque liste) renvoie la valeur minimum des X, Y et Z (X_MIN, Y_MIN (DLformz2
et Z_MIN). (SGqdrhxa
Un “(apply max ... sur chaque liste) renvoie la valeur maximum des X,Y et Z (X_MAX, (vector x_min y_min z_min 1)
Y_MAX et Z_MAX). (vector
Le centre est trouvé en prenant les moyennes des min et max de chaque coordonnée (vector x_cen y_cen z_cen 1)
(X_CEN, Y_CEN et Z_CEN). (vector 1 0 0 0)
On utilise SGqdrhxa pour définir la quadrique qui englobe un hexaèdre défini sur les (vector 0 1 0 0)
valeurs obtenues. (vector 0 0 1 0)
)
;———————————————————————————————————- )
;MIN_MAX )
;évalue le min-max d’un nuage de points )
;paramètre: )
;liste_point liste des points à évaluer )
;variables: ;————————————————————————————————-
;lx, ly, lz liste des x, des y et des z des points ;COMMENTAIRES:
;*_min, *_max valeur minimum et maximum des x, y et z ;————————————————————————————————-
;*_cen valeur du centre des x y et z
;retour:
;quadrique englobant tous ces points
;———————————————————————————————————-

Page 46
EXÉCUTION du VOLUMIQUE (
(= (car t_v) 3)
Le deuxième ensemble de fonctions permet de concrétiser la définition géométrique en (cons (panneau0 pt tr c_p e) r)
forme et matière. On passe du sommet au nœud, du segment à la membrure et du triangle )
au panneau. (
Toutes les paramètres de choix ont été décidés dans VOLU_DEF et transférés à la (= (car t_v) 4)
première fonction d’exécution de ce fichier VOLU_EXE. (cons (panneau1 pt tr c_p e l) r)
On va donc voir cette fonction et toutes celles qu’elle appelle. )
)
)
;——————————————————————————————————
)
;VOLU_EXE
)
;exécute la matérialisation du fichier volumique à partir des données
)
;géométriques selon les choix faits avec VOLU_DEF.scm
)
;paramètres:
)
;vg liste des valeurs des paramètres
)
;retour:
;——————————————————————————————————
;fichier volumique SGDL (*.sl)
;COMMENTAIRES:
;——————————————————————————————————
;toutes les matérialisations sont cumulées par DLmax.
(define volu_exe
;——————————————————————————————————
(lambda (vg)
(let*
(
(points (list-ref vg 0))
(triangles (list-ref vg 1))
(c_sph (list-ref vg 2))
(r_sph (list-ref vg 3))
(c_cyl (list-ref vg 4))
(r_cyl (list-ref vg 5))
(c_pan (list-ref vg 6))
(ep (list-ref vg 7))
(la (list-ref vg 8))
(tv (list-ref vg 9))
(quadmmx (list-ref vg 10))
)
(DLmmx
quadmmx
(let boucle
(
(c_s c_sph)(r_s r_sph)(c_c c_cyl)(r_c r_cyl)(c_p c_pan)
(e ep)(l la)(pt points)(tr triangles)(t_v tv)
(r (list))
)
(if
(null? t_v)
(apply DLmax r)
(boucle
c_s r_s c_c r_c c_p e l pt tr (cdr t_v)
(cond
(
(= (car t_v) 1)
(cons (sommets pt c_s r_s) r)
)
(
(= (car t_v) 2)
(cons (arete (tri_seg tr)) pt c_c r_c) r)
)

Page 47
;---------------------------------------------------------------------------------------------
AUTOCAD ;DOME
;fonction de lecture et de tracé des données géométriques issues des
;fonctions SCHEME sous SGDLsoft d'un dôme géodésique.
;---------------------------------------------------------------------------------------------
Pour permettre à d’autres logiciel de matérialiser le dôme calculé, on a ;GRCAO: par Claude Parisel
;---------------------------------------------------------------------------------------------
fait un exercice de lecture et mise en forme du fichier de points et de
;f_data est le fichier généré en scheme des données du dôme
triangles générés avec Autocad. ;---------------------------------------------------------------------------------------------
(defun dome (f_data)
Pour cela on a écrit une petite fonction en Autolisp qui matérialise le ;Lecture du fichier
dôme en points et triangles par des 3Dfaces. (setq fich (open f_data "r"))
(setq data (read (read-line fich)))
Les points pourraient prendre la forme d’une sphère et les segments des (close fich)
triangles celle d’un cylindre. ;Séparation de la liste des points de celle des triangles
(setq pts (car data))
(setq tri (cadr data))
;Initialisation de la liste des points n_p à vide
(setq n_p (list))
;Définition de la forme des points
(setvar "PDMODE" 33)
(setvar "PDSIZE" 1)
(setvar "CMDECHO" 0)
;élimination des vecteurs et changement de repère
(mapcar
'(lambda (x)
(if (not (atom x))
(setq n_p (cons (list (car x)(- (caddr x))(cadr x)) n_p))
)
)
pts)
(setq n_p (reverse n_p))
;construction des sommets
;(mapcar '(lambda (x) (command "point" x)) n_p)
;construction des triangles
(mapcar
'(lambda (x)
(command "3dface"
(nth (- (car x) 1) n_p)
(nth (- (cadr x) 1) n_p)
(nth (- (last x) 1) n_p)
"" ""
)
)
tri)
)
;------------------------------------------------------------------------

Page 48

Vous aimerez peut-être aussi