1 |
% $Id$ |
% $Id$ |
2 |
|
|
3 |
\chapter{Comment modéliser la géométrie euclidienne ?} |
\chapter{Comment modéliser la géométrie euclidienne ?} |
4 |
|
\minitoc{} |
5 |
|
|
6 |
Nous allons voir ici comment il est possible de représenter en mémoire des objets géométriques sans les décrire de manière analytique. |
Nous allons voir ici comment il est possible de représenter en mémoire |
7 |
|
des objets géométriques sans les décrire de manière analytique. |
8 |
|
|
9 |
\section{Le choix des objets de base} |
\section{Le choix des objets de base} |
10 |
La géometrie euclidienne est un ensemble d'objets (point, droite, triangle, carré, polygone, angle, cercle ...) et de propriétés sur ces objets (perpendiculaire, parrallèle, milieu, inscrit, circonscrit ...). |
La géometrie euclidienne est un ensemble d'objets (point, droite, |
11 |
|
triangle, carré, polygone, angle, cercle ...) et de propriétés sur ces |
12 |
La multitude de ces objets et de leurs propriétés rend difficile la modélisation. En effet si l'on veut donner une représentation pour tous les objets existants en géométrie, on obtient un modèle trop lourd et trop constraignant dans son utilisation. Pour les mêmes raisons, on ne peut exprimer l'ensemble de toutes les propriétés disponibles en géométrie. L'idée est de créer un modèle 'minimal' contenant des objets et propriétés de base avec lesquels il est possible d'engendrer différentes figures géométriques. |
objets (perpendiculaire, parrallèle, milieu, inscrit, circonscrit |
13 |
|
...). |
14 |
La difficulté consiste donc à bien choisir ces objets de base. Pour cela revenons à nos cours de géométrie du collège. Tout élève de 6ème sait qu'une figure géométrique peut se construire uniquement à l'aide de la règle et du compas. Autrement dit à partir de droites et de cercles, il est possible de créer n'importe qu'elle figure. |
|
15 |
|
La multitude de ces objets et de leurs propriétés rend difficile la |
16 |
Le traçage d'une droite à la règle nécessite la connaissance de deux points. De même un cercle se définit par son centre et son rayon: ce qui nécessite également deux points. Droite et cercle peuvent donc être vus comme des couples de points. Mais qu'est-ce qu'un point ? |
modélisation. En effet si l'on veut donner une représentation pour |
17 |
|
tous les objets existants en géométrie, on obtient un modèle trop |
18 |
|
lourd et trop constraignant dans son utilisation. Pour les mêmes |
19 |
|
raisons, on ne peut exprimer l'ensemble de toutes les propriétés |
20 |
|
disponibles en géométrie. L'idée est de créer un modèle 'minimal' |
21 |
|
contenant des objets et propriétés de base avec lesquels il est |
22 |
|
possible d'engendrer différentes figures géométriques. |
23 |
|
|
24 |
|
La difficulté consiste donc à bien choisir ces objets de base. Pour |
25 |
|
cela revenons à nos cours de géométrie du collège. Tout élève de 6ème |
26 |
|
sait qu'une figure géométrique peut se construire uniquement à l'aide |
27 |
|
de la règle et du compas. Autrement dit à partir de droites et de |
28 |
|
cercles, il est possible de créer n'importe qu'elle figure. |
29 |
|
|
30 |
|
Le traçage d'une droite à la règle nécessite la connaissance de deux |
31 |
|
points. De même un cercle se définit par son centre et son rayon: ce |
32 |
|
qui nécessite également deux points. Droite et cercle peuvent donc |
33 |
|
être vus comme des couples de points. Mais qu'est-ce qu'un point ? |
34 |
|
|
35 |
Si l'on se ramène à la géométrie constructive on voit qu'il n'y a pas beaucoup de manières de constuire un point: |
Si l'on se ramène à la géométrie constructive on voit qu'il n'y a pas beaucoup de manières de constuire un point: |
36 |
\begin{itemize} |
\begin{itemize} |
60 |
|
|
61 |
\section{Arbre de construction} |
\section{Arbre de construction} |
62 |
|
|
63 |
La représentation d'un point par un arbre de construction plutôt que par des coordonnées est bien sûr plus coûteuse aussi bien en terme d'espace mémoire que de temps d'accès, mais comme nous le verrons plus tard elle possède de nombreux avantages. |
La représentation d'un point par un arbre de construction plutôt que |
64 |
|
par des coordonnées est bien sûr plus coûteuse aussi bien en terme |
65 |
Avec un arbre, on mémorise non pas une positon exacte du point (comme avec les coordonées) mais une position relative par rapport à des objets qui existent déjà. L'arbre de construction d'un point n'est donc rien d'autre que l'algorithme permettant de le construire. |
d'espace mémoire que de temps d'accès, mais comme nous le verrons plus |
66 |
|
tard elle possède de nombreux avantages. |
67 |
Pour illustrer cela, considérons un exemple simple. Soit A et B deux point quelconques. Comment construire I milieu du segment [AB] ? |
|
68 |
|
Avec un arbre, on mémorise non pas une positon exacte du point (comme |
69 |
Il faut tout d'abord tracer le cercle C1 de centre A et passant par le point B. Puis le cercle C2 de centre B et passant par le point A. Les cercles C1 et C2 se coupent alors en deux points: C et D. Traçons ensuite la droite (CD) passant par C et D. Le point I est alors l'intersection entre la droite (CD) et le segment [AB].On obtient alors la construction suivante: |
avec les coordonées) mais une position relative par rapport à des |
70 |
|
objets qui existent déjà. L'arbre de construction d'un point n'est |
71 |
|
donc rien d'autre que l'algorithme permettant de le construire. |
72 |
|
|
73 |
|
\paragraph{Exemple} Soit A et B deux |
74 |
|
point quelconques. Comment construire I milieu du segment [AB] ? |
75 |
|
|
76 |
|
Il faut |
77 |
|
\begin{enumerate} |
78 |
|
\item tracer le cercle C1 de centre A et passant par le |
79 |
|
point B. |
80 |
|
\item puis le cercle C2 de centre B et passant par le point A. |
81 |
|
\item les |
82 |
|
cercles C1 et C2 se coupent alors en deux points: C et D. |
83 |
|
\item tracer ensuite la droite (CD) passant par C et D. |
84 |
|
\end{enumerate} |
85 |
|
|
86 |
|
Le point I est alors |
87 |
|
l'intersection entre la droite (CD) et le segment [AB].On obtient |
88 |
|
alors la construction suivante: |
89 |
|
|
90 |
\begin{pspicture}(-7,-3.5)(10,4) |
\begin{pspicture}(-7,-3.5)(10,4) |
91 |
\pstGeonode(-2,0){A} |
\pstGeonode(-2,0){A} |
132 |
} |
} |
133 |
\end{pspicture} |
\end{pspicture} |
134 |
|
|
135 |
Analysons cet arbre. Lorsque le noeud est un point, on l'obtient en traçant l'intersection de ses deux fils. Si c'est une droite, elle passe par les deux fils (qui sont donc obligatoirement des points). Pour un cercle, le fils gauche sera par convention le centre et le fils droit un point de sa circonférence. Une feuille sera par définition soit un point déjà construit, soit un point quelconque. |
Analysons cet arbre. Lorsque le noeud est un point, on l'obtient en |
136 |
|
traçant l'intersection de ses deux fils. Si c'est une droite, elle |
137 |
|
passe par les deux fils (qui sont donc obligatoirement des |
138 |
|
points). Pour un cercle, le fils gauche sera par convention le centre |
139 |
|
et le fils droit un point de sa circonférence. Une feuille sera par |
140 |
|
définition soit un point déjà construit, soit un point quelconque. |
141 |
|
|
142 |
\section{Implémentation Caml} |
\section{Implémentation Caml} |
143 |
|
|
144 |
Il faut tout d'abord représenter les objets de base sous un même type. Pour cela le langage Caml nous offre les constructeurs constants que l'on peut utiliser avec un type énuméré. On obtient ainsi: |
Il faut tout d'abord représenter les objets de base sous un même |
145 |
|
type. Pour cela le langage Caml nous offre les constructeurs constants |
146 |
|
que l'on peut utiliser avec un type énuméré. On obtient ainsi: |
147 |
|
|
148 |
\begin{verbatim} |
\begin{verbatim} |
149 |
type geometry_object = Point | Line | Circle |
type geometry_object = Point | Line | Circle |
150 |
\end{verbatim} |
\end{verbatim} |
151 |
|
|
152 |
Maintenant nous devons créer le type arbre lui-même. Un noeud de l'arbre devra comporter le type de l'objet à construire, son nom afin de pouvoir le différencier de ses congénères (sous forme d'une chaine de caractères) et enfin ses deux fils. Là encore, on utilise les constructeurs, mais cette fois-ci l'un sera constant et l'autre fonctionnel: |
Maintenant nous devons créer le type arbre lui-même. Un noeud de |
153 |
|
l'arbre devra comporter le type de l'objet à construire, son nom afin |
154 |
|
de pouvoir le différencier de ses congénères (sous forme d'une chaine |
155 |
|
de caractères) et enfin ses deux fils. Là encore, on utilise les |
156 |
|
constructeurs, mais cette fois-ci l'un sera constant et l'autre |
157 |
|
fonctionnel: |
158 |
|
|
159 |
\begin{verbatim} |
\begin{verbatim} |
160 |
type abr = Empty | Node of node |
type abr = Empty | Node of node |
164 |
right_obj: abr } |
right_obj: abr } |
165 |
\end{verbatim} |
\end{verbatim} |
166 |
|
|
167 |
Afin d'utiliser plus simplement notre structure d'arbre nous pouvons écrire des fonctions de manipulation retournant des noeuds pour un point, une droite et un cercle: |
Afin d'utiliser plus simplement notre structure d'arbre nous pouvons |
168 |
|
écrire des fonctions de manipulation retournant des noeuds pour un |
169 |
|
point, une droite et un cercle: |
170 |
|
|
171 |
\begin{verbatim} |
\small{\begin{verbatim} |
172 |
let point name (obj1,obj2) = |
let point name (obj1,obj2) = |
173 |
Node {obj = Point ; |
Node {obj = Point ; |
174 |
label = name ; left_obj = obj1 ; right_obj = obj2} |
label = name ; left_obj = obj1 ; right_obj = obj2} |
180 |
let circle name (point1,point2) = |
let circle name (point1,point2) = |
181 |
Node {obj = Circle ; |
Node {obj = Circle ; |
182 |
label = name ; left_obj = point1 ; right_obj = point2} |
label = name ; left_obj = point1 ; right_obj = point2} |
183 |
\end{verbatim} |
\end{verbatim}} |
184 |
|
|
185 |
Ces 3 fonctions nécessitent à chaque fois que l'on fournisse un nom pour pouvoir plus tard identifier l'objet. Or tous les points d'une figure ne seront pas nécessairement déclarés par l'utilisateur: c'est le cas par exemple des points intermédiaires utilisés lors d'une constrution. Le nombre de points intermédiaires dans une figure pouvant être relativement important, il faut pouvoir assurer que chacun de ces points aura un nom différent. Pour cela nous allons écrire des générateurs de noms. On va alors déclarer une référence sur un entier dans une fonction qui va à chaque appel l'incrémenter et le concaténer à une chaine de caractères servant de base: |
Ces 3 fonctions nécessitent à chaque fois que l'on fournisse un nom |
186 |
|
pour pouvoir plus tard identifier l'objet. Or tous les points d'une |
187 |
|
figure ne seront pas nécessairement déclarés par l'utilisateur: c'est |
188 |
|
le cas par exemple des points intermédiaires utilisés lors d'une |
189 |
|
constrution. Le nombre de points intermédiaires dans une figure |
190 |
|
pouvant être relativement important, il faut pouvoir assurer que |
191 |
|
chacun de ces points aura un nom différent. Pour cela nous allons |
192 |
|
écrire des générateurs de noms. On va alors déclarer une référence sur |
193 |
|
un entier dans une fonction qui va à chaque appel l'incrémenter et le |
194 |
|
concaténer à une chaine de caractères servant de base: |
195 |
|
|
196 |
\begin{verbatim} |
\begin{verbatim} |
197 |
let name base = |
let name base = |
218 |
- : string = "p2" |
- : string = "p2" |
219 |
\end{verbatim} |
\end{verbatim} |
220 |
|
|
221 |
On peut maintenant passer à l'écriture de fonctions plus compliquées, comme celle permettant de construire un milieu. Le code est assez naturel et se rapproche fortement d'un énoncé en français: |
On peut maintenant passer à l'écriture de fonctions plus compliquées, |
222 |
|
comme celle permettant de construire un milieu. Le code est assez |
223 |
|
naturel et se rapproche fortement d'un énoncé en français: |
224 |
|
|
225 |
\begin{verbatim} |
\begin{verbatim} |
226 |
let middle name pointA pointB = |
let middle name pointA pointB = |
235 |
|
|
236 |
Toutes les autres fonctions permettant de tracer droites parallèles, perpendiculaires, etc... sont calquées sur ce modèle. |
Toutes les autres fonctions permettant de tracer droites parallèles, perpendiculaires, etc... sont calquées sur ce modèle. |
237 |
|
|
238 |
\chapter{Dessin géométrique et visualisation} |
\chapter{Visualisation des tracés géométriques} |
239 |
|
\minitoc{} |
|
Maintenant que nous disposons d'objets en mémoire, il serait agréable de pouvoir en donner une visualisation graphique. Ici encore, il est intéressant de se démarquer des logiciels existants. En effet, un élève qui utilise Cabri pour tracer le milieu d'un segment obtient juste un point, sans savoir comment celui-ci a été construit. Et pour cause, Cabri ne contruit pas de points, mais les calcule. Notre représentation sous forme d'arbre permettrait également de calculer des coordonnées et de les afficher, mais il serait beaucoup plus intéressant de faire apparaitre à l'écran, en plus du point, la méthode qui a permis de l'obtenir. |
|
240 |
|
|
241 |
L'idée serait de disposer de deux fonctions simulant le fonctionnement d'une règle et d'un compas. Outre le traçage de droites et de cercles, elles permettraient de retourner les points d'intersection avec les différents objets rencontrés. Le problème qui se pose alors est de pouvoir différencier visuellement les différents objets présents à l'écran. |
Maintenant que nous disposons d'objets en mémoire, il serait agréable |
242 |
|
de pouvoir en donner une visualisation graphique. Ici encore, il est |
243 |
|
intéressant de se démarquer des logiciels existants. En effet, un |
244 |
|
élève qui utilise Cabri pour tracer le milieu d'un segment obtient |
245 |
|
juste un point, sans savoir comment celui-ci a été construit. Et pour |
246 |
|
cause, Cabri ne contruit pas de points, mais les calcule. Notre |
247 |
|
représentation sous forme d'arbre permettrait également de calculer |
248 |
|
des coordonnées et de les afficher, mais il serait beaucoup plus |
249 |
|
intéressant de faire apparaitre à l'écran, en plus du point, la |
250 |
|
méthode qui a permis de l'obtenir. |
251 |
|
|
252 |
|
L'idée serait de disposer de deux fonctions simulant le fonctionnement |
253 |
|
d'une règle et d'un compas. Outre le traçage de droites et de cercles, |
254 |
|
elles permettraient de retourner les points d'intersection avec les |
255 |
|
différents objets rencontrés. Le problème qui se pose alors est de |
256 |
|
pouvoir différencier visuellement les différents objets présents à |
257 |
|
l'écran. |
258 |
|
|
259 |
\section{Repérage des objets géométriques à l'écran} |
\section{Repérage des objets géométriques à l'écran} |
260 |
|
|
261 |
Dans sa bibliothèque graphique, le Caml fournit une fonction permettant pour un point à l'écran donné, de retourner un entier correspondant à sa couleur. Il est donc possible de distinguer les objets par leur couleur. Il suffit à chaque fois que l'on trace une droite ou un cercle de s'assurer que sa couleur soit différente des objets déjà présents à l'écran. Comme dans le chapitre précédent, il faut écrire des fonctions permettant de générer automatiquement des codes couleurs. |
Dans sa bibliothèque graphique, le Caml fournit une fonction |
262 |
|
permettant pour un point à l'écran donné, de retourner un entier |
263 |
Pour représenter les couleurs, le Caml utilise trois octets: chacun est la valeur de l'intensité d'une couleur principale dans le modèle RGB (rouge,vert,bleu) comprise entre 0 et 255. Le système graphique du Caml autorise donc 16 millions de couleur. Pour une même couleur, il est donc possible d'extraire des nuances indiscernables à l'oeil. |
correspondant à sa couleur. Il est donc possible de distinguer les |
264 |
|
objets par leur couleur. Il suffit à chaque fois que l'on trace une |
265 |
Nous allons donc baser l'affichage sur 4 couleurs: noir, rouge, vert, bleu. A chaucne de ces 4 couleurs, on associe une fonction qui va retourner un code RGB suivant ces contraintes: |
droite ou un cercle de s'assurer que sa couleur soit différente des |
266 |
|
objets déjà présents à l'écran. Comme dans le chapitre précédent, il |
267 |
|
faut écrire des fonctions permettant de générer automatiquement des |
268 |
|
codes couleurs. |
269 |
|
|
270 |
|
Pour représenter les couleurs, le Caml utilise trois octets: chacun |
271 |
|
est la valeur de l'intensité d'une couleur principale dans le modèle |
272 |
|
RGB (rouge,vert,bleu) comprise entre 0 et 255. Le système graphique du |
273 |
|
Caml autorise donc 16 millions de couleur. Pour une même couleur, il |
274 |
|
est donc possible d'extraire des nuances indiscernables à l'oeil. |
275 |
|
|
276 |
|
Nous allons donc baser l'affichage sur 4 couleurs: noir, rouge, vert, |
277 |
|
bleu. A chaucne de ces 4 couleurs, on associe une fonction qui va |
278 |
|
retourner un code RGB suivant ces contraintes: |
279 |
|
|
280 |
$$ |
$$ |
281 |
noir = \left\lbrace |
noir = \left\lbrace |
316 |
\right. |
\right. |
317 |
$$ |
$$ |
318 |
|
|
319 |
Cela nous offre la possibilité de construire et d'afficher 32000 objets. Ces contraintes sont utilisées pour l'écriture des fonctions de génération. Le mécanisme d'exception du langage Caml, intervient lorsqu'une fonction associée à une couleur a généré ses 8000 codes RGB et se trouve dans un un état de dépassement de capacité. Voici par exemple le code pour la couleur noire: |
Cela nous offre la possibilité de construire et d'afficher 32000 |
320 |
|
objets. Ces contraintes sont utilisées pour l'écriture des fonctions |
321 |
|
de génération. Le mécanisme d'exception du langage Caml, intervient |
322 |
|
lorsqu'une fonction associée à une couleur a généré ses 8000 codes RGB |
323 |
|
et se trouve dans un un état de dépassement de capacité. Voici par |
324 |
|
exemple le code pour la couleur noire: |
325 |
|
|
326 |
\begin{verbatim} |
\begin{verbatim} |
327 |
exception Too_many_black_object |
exception Too_many_black_object |
336 |
else raise Too_many_black_object) |
else raise Too_many_black_object) |
337 |
\end{verbatim} |
\end{verbatim} |
338 |
|
|
339 |
A présent, nous sommes en mesure de repérer les objets à l'écran. Etudions donc comment implémenter une règle et un compas 'virtuel'. |
A présent, nous sommes en mesure de repérer les objets à |
340 |
|
l'écran. Etudions donc comment implémenter une règle et un compas |
341 |
\section{Simulation de la règle} |
'virtuel'. |
342 |
|
|
343 |
La bibliothèque graphique de Caml offre une fonction de tracé de lignes. Hélas, nous ne pouvons pas l'utiliser ici car nous avons besoin de tracer une droite point par point et de vérifier à chaque fois si le point que l'on s'apprête à afficher n'appartient pas déjà à un autre objet. |
\section{La règle} |
344 |
|
|
345 |
Il faut donc réécrire une fonction. Pour cela, il existe de nombreux algorithmes bien éprouvés. Le plus célèbre et le meilleur est celui de Bresenham. Son principe consiste à approcher la ligne réelle par un ensemble de points allumés. Tout reste à savoir quels sont les pixels à allumer. |
La bibliothèque graphique de Caml offre une fonction de tracé de |
346 |
|
lignes. Hélas, nous ne pouvons pas l'utiliser ici car nous avons |
347 |
|
besoin de tracer une droite point par point et de vérifier à chaque |
348 |
|
fois si le point que l'on s'apprête à afficher n'appartient pas déjà à |
349 |
|
un autre objet. |
350 |
|
|
351 |
|
Il faut donc réécrire une fonction. Pour cela, il existe de nombreux |
352 |
|
algorithmes bien éprouvés. Le plus célèbre et le meilleur est celui de |
353 |
|
Bresenham. Son principe consiste à approcher la ligne réelle par un |
354 |
|
ensemble de points allumés. Tout reste à savoir quels sont les pixels |
355 |
|
à allumer. |
356 |
|
|
357 |
Si $(x_1,y_1)$ sont les coordonnées du début de la ligne à afficher et $(x_2,y_2)$ ses coordonnées de fin, on va poser: |
Si $(x_1,y_1)$ sont les coordonnées du début de la ligne à afficher et $(x_2,y_2)$ ses coordonnées de fin, on va poser: |
358 |
\begin{center} |
\begin{center} |
362 |
\begin{center} |
\begin{center} |
363 |
$D_x < D_y \ et \ x_1 < x_2$ |
$D_x < D_y \ et \ x_1 < x_2$ |
364 |
\end{center} |
\end{center} |
365 |
La pente de la ligne à afficher est donnée par $\frac{D_y}{D_x}$. La méthode utilisée consiste à allumer des pixels dans une seule direction, ici la direction $x$, et n'allumer de pixels dans la direction $y$ que si l'erreur entre la pente obtenue et la pente idéale dépasse un certain seuil. Ainsi, si $(x,y)$ sont les coordonnées du point courant (en cours d'affichage), on aura: |
|
366 |
|
La pente de la ligne à afficher est donnée par $\frac{D_y}{D_x}$. La |
367 |
|
méthode utilisée consiste à allumer des pixels dans une seule |
368 |
|
direction, ici la direction $x$, et n'allumer de pixels dans la |
369 |
|
direction $y$ que si l'erreur entre la pente obtenue et la pente |
370 |
|
idéale dépasse un certain seuil. Ainsi, si $(x,y)$ sont les |
371 |
|
coordonnées du point courant (en cours d'affichage), on aura: |
372 |
|
|
373 |
\begin{center} |
\begin{center} |
374 |
$ y = y_1 + ( x - x_1 ) \times \frac{D_y}{D_x}$ |
$ y = y_1 + ( x - x_1 ) \times \frac{D_y}{D_x}$ |
375 |
\end{center} |
\end{center} |
379 |
\end{center} |
\end{center} |
380 |
Ce qui fait que l'erreur commise si l'on allume un point dans la direction $x$ est de $\frac{D_y}{D_x}$. |
Ce qui fait que l'erreur commise si l'on allume un point dans la direction $x$ est de $\frac{D_y}{D_x}$. |
381 |
|
|
382 |
L'erreur est cumulée dans une variable. A chaque fois on l'incrémente de $\frac{D_y}{D_x}$ et l'on commence à allumer des points dans l'autre direction dès que l'erreur dépasse la valeur $1$. Au niveau du code, il faut tenir compte des autres cas possibles: $D_x > D_y$ et $ x_1 > x_2$. Ce qui nous donne la fonction règle suivante: |
L'erreur est cumulée dans une variable. A chaque fois on l'incrémente |
383 |
|
de $\frac{D_y}{D_x}$ et l'on commence à allumer des points dans |
384 |
|
l'autre direction dès que l'erreur dépasse la valeur $1$. Au niveau du |
385 |
|
code, il faut tenir compte des autres cas possibles: $D_x > D_y$ et $ |
386 |
|
x_1 > x_2$. Ce qui nous donne la fonction règle suivante: |
387 |
|
|
388 |
\begin{verbatim} |
\begin{verbatim} |
389 |
let règle (x1,y1) (x2,y2) = |
let règle (x1,y1) (x2,y2) = |
415 |
end) |
end) |
416 |
\end{verbatim} |
\end{verbatim} |
417 |
|
|
418 |
A l'intérieur de cette fonction, il faut maintenant vérifier si le point courant que l'on souhaite afficher n'est pas un point d'intersection. Nous allons donc écrire une autre fonction qui permettra de vérifier pour un point donné s'il appartient déjà à un autre objet. |
A l'intérieur de cette fonction, il faut maintenant vérifier si le |
419 |
|
point courant que l'on souhaite afficher n'est pas un point |
420 |
Cette fonction n'est pas si simple à écrire et pose plusieurs problèmes. Tout d'abord, on doit mémoriser les points d'intersections que l'on rencontre. Dans cette configuration, un point d'intersection est un couple: $( coordonnée \ du \ \ pixel , couleur \ du \ pixel)$ et la structure la plus appropriée pour mémoriser cela est une liste. Ensuite, comme le montre les figures 2.1 et 2.2, il ne suffit pas que le pixel courant ne soit pas encore allumé pour affirmer qu'il ne représentera pas un point d'intersection: il faut aussi vérifier les pixels voisins. |
d'intersection. Nous allons donc écrire une autre fonction qui |
421 |
|
permettra de vérifier pour un point donné s'il appartient déjà à un |
422 |
|
autre objet. |
423 |
|
|
424 |
|
Cette fonction n'est pas si simple à écrire et pose plusieurs |
425 |
|
problèmes. Tout d'abord, on doit mémoriser les points d'intersections |
426 |
|
que l'on rencontre. Dans cette configuration, un point d'intersection |
427 |
|
est un couple: $( coordonnée \ du \ \ pixel , couleur \ du \ pixel)$ |
428 |
|
et la structure la plus appropriée pour mémoriser cela est une |
429 |
|
liste. Ensuite, comme le montre les figures 2.1 et 2.2, il ne suffit |
430 |
|
pas que le pixel courant ne soit pas encore allumé pour affirmer qu'il |
431 |
|
ne représentera pas un point d'intersection: il faut aussi vérifier |
432 |
|
les pixels voisins. |
433 |
|
|
434 |
\begin{center} |
\begin{center} |
435 |
\begin{pspicture}(4,3) |
\begin{pspicture}(4,3) |
485 |
\end{pspicture} |
\end{pspicture} |
486 |
\end{center} |
\end{center} |
487 |
|
|
488 |
De même, lorsque les lignes ont plus d'un pixel en commun, tous ces pixels ne peuvent représenter des intersections: il ne nous faut qu'un seul point! L'idée est donc de comparer coordonnées et couleur du pixel courant à tous les points de la liste afin de vérifier qu'il n'y a pas 'redondance'. Au niveau du code, cela nous donne les deux fonctions \verb+check_intersection+ et \verb+not_in_the_same_locus+ (cf Annexe). Il suffit alors d'appliquer la fonction \verb+check_intersection+ juste avant d'afficher le point courant. |
De même, lorsque les lignes ont plus d'un pixel en commun, tous ces |
489 |
|
pixels ne peuvent représenter des intersections: il ne nous faut qu'un |
490 |
Au final, on obtient la fonction \verb+ruler+ (cf Annexe) qui permet grâçe à deux couples de coordonnées de tracer une droite et de retourner la liste des points d'intersection avec les différents objets rencontrés. |
seul point! L'idée est donc de comparer coordonnées et couleur du |
491 |
|
pixel courant à tous les points de la liste afin de vérifier qu'il n'y |
492 |
\section{Simulation du compas} |
a pas 'redondance'. Au niveau du code, cela nous donne les deux |
493 |
|
fonctions \verb+check_intersection+ et \verb+not_in_the_same_locus+ |
494 |
Le même problème se pose ici, nous ne pouvons utiliser la fonction prédéfinie du Caml pour tracer des cercles, il nous faut pouvoir effectuer un tracé au point par point. Une des méthodes les plus simples pour tracer un cercle est alors d'utiliser les coordonnées polaires qui vont permettre de faire apparaitre un angle. Si les coordonnées du point courant sont $(x,y)$, on a: |
(cf Annexe). Il suffit alors d'appliquer la fonction |
495 |
|
\verb+check_intersection+ juste avant d'afficher le point courant. |
496 |
|
|
497 |
|
Au final, on obtient la fonction \verb+ruler+ (cf Annexe) qui permet |
498 |
|
grâçe à deux couples de coordonnées de tracer une droite et de |
499 |
|
retourner la liste des points d'intersection avec les différents |
500 |
|
objets rencontrés. |
501 |
|
|
502 |
|
\section{Le compas} |
503 |
|
|
504 |
|
Le même problème se pose ici, nous ne pouvons utiliser la fonction |
505 |
|
prédéfinie du Caml pour tracer des cercles, il nous faut pouvoir |
506 |
|
effectuer un tracé au point par point. Une des méthodes les plus |
507 |
|
simples pour tracer un cercle est alors d'utiliser les coordonnées |
508 |
|
polaires qui vont permettre de faire apparaitre un angle. Si les |
509 |
|
coordonnées du point courant sont $(x,y)$, on a: |
510 |
\begin{center} |
\begin{center} |
511 |
$$\left\lbrace |
$$\left\lbrace |
512 |
\begin{array}{l} |
\begin{array}{l} |
532 |
done |
done |
533 |
\end{verbatim} |
\end{verbatim} |
534 |
|
|
535 |
Comme pour dans la partie précédente, il faut vérifier si le point courant que l'on va tracer est une intersection avec un autre objet ou non. Pour cela les fonctions \verb+check_intersection+ et \verb+not_in_the_same_locus+ expliquées précédemment peuvent être réutilisées de la même manière. |
Comme pour dans la partie précédente, il faut vérifier si le point |
536 |
|
courant que l'on va tracer est une intersection avec un autre objet ou |
537 |
Tout ceci nous donne la fonction \verb+compasses+ (cf Annexe) qui à partir d'un centre et d'un rayon trace un cercle et retourne les points d'intersections avec tous les objets rencontrés. Disposant maintenant des deux outils nécessaires à toute construction géométrique, nous allons pouvoir générer à partir d'un arbre un affichage graphique. |
non. Pour cela les fonctions \verb+check_intersection+ et |
538 |
|
\verb+not_in_the_same_locus+ expliquées précédemment peuvent être |
539 |
|
réutilisées de la même manière. |
540 |
|
|
541 |
|
Tout ceci nous donne la fonction \verb+compasses+ (cf Annexe) qui à |
542 |
|
partir d'un centre et d'un rayon trace un cercle et retourne les |
543 |
|
points d'intersections avec tous les objets rencontrés. Disposant |
544 |
|
maintenant des deux outils nécessaires à toute construction |
545 |
|
géométrique, nous allons pouvoir générer à partir d'un arbre un |
546 |
|
affichage graphique. |
547 |
|
|
548 |
\section{Parcours d'arbre et affichage graphique} |
\section{Parcours d'arbre et affichage graphique} |
549 |
|
|
550 |
L'obtention de l'affichage graphique d'un objet passe par le parcours de l'arbre de construction de celui-ci. Ce parcours doit bien entendu être postfixé puisque comme nous l'avons vu au chapitre 1, la construction de la racine dépend de celle de ses deux fils. Lors de ce parcours, il faut pouvoir faire l'association entre le 'nom symbolique' de l'objet (représenté par le champ \verb+label+ dans la structure d'arbre) et son 'identifiant graphique' (représenté par son code couleur). Par ailleurs, il faut pouvoir mémoriser les objets existants afin d'éviter de les reconstruire à chaque fois. |
L'obtention de l'affichage graphique d'un objet passe par le parcours |
551 |
|
de l'arbre de construction de celui-ci. Ce parcours doit bien entendu |
552 |
|
être postfixé puisque comme nous l'avons vu au chapitre 1, la |
553 |
|
construction de la racine dépend de celle de ses deux fils. Lors de ce |
554 |
|
parcours, il faut pouvoir faire l'association entre le 'nom |
555 |
|
symbolique' de l'objet (représenté par le champ \verb+label+ dans la |
556 |
|
structure d'arbre) et son 'identifiant graphique' (représenté par son |
557 |
|
code couleur). Par ailleurs, il faut pouvoir mémoriser les objets |
558 |
|
existants afin d'éviter de les reconstruire à chaque fois. |
559 |
|
|
560 |
Nous allons donc déclarer en variable globale 3 listes: une pour les points déjà construits, une deuxième pour les droites et une troisième pour les cercles: |
Nous allons donc déclarer en variable globale 3 listes: une pour les points déjà construits, une deuxième pour les droites et une troisième pour les cercles: |
561 |
\begin{itemize} |
\begin{itemize} |
585 |
l_id=-1 ; |
l_id=-1 ; |
586 |
l_intersection=[((-1,-1),{contents=-1})]}] |
l_intersection=[((-1,-1),{contents=-1})]}] |
587 |
\end{verbatim} |
\end{verbatim} |
588 |
\item enfin la liste des cercles va contenir noms, coordonnées des centres, rayons, couleurs et pour chaque cercle la liste d'intersection obtenue lors du traçage avec la fonction \verb+compasses+ (cf Annexe): |
\item enfin la liste des cercles va contenir noms, coordonnées des |
589 |
|
centres, rayons, couleurs et pour chaque cercle la liste |
590 |
|
d'intersection obtenue lors du traçage avec la fonction |
591 |
|
\verb+compasses+ (cf Annexe): |
592 |
|
|
593 |
\begin{verbatim} |
\begin{verbatim} |
594 |
type circle_drawn = |
type circle_drawn = |
595 |
{c_label: string ; |
{c_label: string ; |
604 |
c_radius = -1 ; |
c_radius = -1 ; |
605 |
c_id = -1 ; |
c_id = -1 ; |
606 |
c_intersection=[((-1,-1),{contents=-1})]}] |
c_intersection=[((-1,-1),{contents=-1})]}] |
|
|
|
607 |
\end{verbatim} |
\end{verbatim} |
608 |
\end{itemize} |
\end{itemize} |
609 |
|
|
610 |
A ces trois listes, on associe les fonctions d'ajout et de recherche suivantes: \verb+search_point_drawn+, \verb+add_point_drawn+, \verb+search_line_drawn+, etc... (cf Annexe). Nous avons également besoin d'une fonction \verb+search_intersection+ permettant de retourner les coordonnées du point d'intersection entre deux objets. |
A ces trois listes, on associe les fonctions d'ajout et de recherche |
611 |
|
suivantes: \verb+search_point_drawn+, \verb+add_point_drawn+, |
612 |
|
\verb+search_line_drawn+, etc... (cf Annexe). Nous avons également |
613 |
|
besoin d'une fonction \verb+search_intersection+ permettant de |
614 |
|
retourner les coordonnées du point d'intersection entre deux objets. |
615 |
|
|
616 |
Le parcours de l'arbre est avant tout basé sur l'analyse des noeuds. Trois cas se présentent donc: |
Le parcours de l'arbre est avant tout basé sur l'analyse des noeuds. Trois cas se présentent donc: |
617 |
\begin{itemize} |
\begin{itemize} |
618 |
\item \textsf{cas 1}: si le noeud est une droite, on commence par regarder si cette droite n'a pas déjà été construite. Si ce n'est pas le cas, il faut alors rechercher les deux points la définissant dans la liste \verb+list_point_drawn+. On génère ensuite une couleur pour le traçage de cette droite et on lance la fonction \verb+ruler+.\\ |
\item \textsf{cas 1}: si le noeud est une droite, on commence par |
619 |
On récupère alors la liste d'intersection de cette droite avec tous les autres objets de la figure. Il ne reste plus ensuite qu'à ajouter cette droite à la liste \verb+list_line_drawn+. |
regarder si cette droite n'a pas déjà été construite. Si ce n'est |
620 |
\item \textsf{cas 2}: si le noeud est un cercle, on fait de même: lorsque le cercle n'a pas déjà été construit, il faut rechercher les coordonnées des deux points qui le définissent puis calculer son rayon. On génère ensuite une couleur et on lance la fonction \verb+compasses+. Celle-ci nous retourne la liste d'intersection de ce cercle avec tous les autres objets de la figure. On peut alors ajouter ce cercle à la liste \verb+list_circle_drawn+. |
pas le cas, il faut alors rechercher les deux points la définissant |
621 |
\item \textsf{cas 3: }si le noeud est un point, deux cas sont alors possibles: |
dans la liste \verb+list_point_drawn+. On génère ensuite une couleur |
622 |
\begin{itemize} |
pour le traçage de cette droite et on lance la fonction |
623 |
\item soit le point est quelconque, il suffit alors de lui générer au hasard des coordonnées et une couleur. Après l'avoir affiché à l'écran, on l'ajoute à la liste \verb+list_point_drawn+. |
\verb+ruler+. |
624 |
|
|
625 |
|
On récupère alors la liste d'intersection de cette droite avec tous |
626 |
|
les autres objets de la figure. Il ne reste plus ensuite qu'à ajouter |
627 |
|
cette droite à la liste \verb+list_line_drawn+. |
628 |
|
|
629 |
|
\item \textsf{cas 2} si le noeud est un cercle, on fait de même: |
630 |
|
lorsque le cercle n'a pas déjà été construit, il faut rechercher les |
631 |
|
coordonnées des deux points qui le définissent puis calculer son |
632 |
|
rayon. On génère ensuite une couleur et on lance la fonction |
633 |
|
\verb+compasses+. Celle-ci nous retourne la liste d'intersection de |
634 |
|
ce cercle avec tous les autres objets de la figure. On peut alors |
635 |
|
ajouter ce cercle à la liste \verb+list_circle_drawn+. |
636 |
|
|
637 |
|
\item \textsf{cas 3} si le noeud est un point, deux cas sont alors possibles: |
638 |
|
\begin{itemize} |
639 |
|
\item soit le point est quelconque, il suffit alors de lui générer au |
640 |
|
hasard des coordonnées et une couleur. Après l'avoir affiché à |
641 |
|
l'écran, on l'ajoute à la liste \verb+list_point_drawn+. |
642 |
\item soit le point doit être construit par intersection. On exécute alors la fonction \verb+search_intersection+ pour obtenir ses coordonnées. Le reste se fait comme pour le point quelconque. |
\item soit le point doit être construit par intersection. On exécute alors la fonction \verb+search_intersection+ pour obtenir ses coordonnées. Le reste se fait comme pour le point quelconque. |
643 |
\end{itemize} |
\end{itemize} |
644 |
\end{itemize} |
\end{itemize} |
645 |
|
|
646 |
\section{Intéret et fiabilité de la méthode} |
\section{Intéret et fiabilité de la méthode} |
647 |
|
|
648 |
Il apparait évident que cette méthode de recherche graphique de points d'intersection est plus coûteuse en terme de complexité temporelle qu'une classique résolution d'équations. On ne peut ainsi obtenir un affichage quasi instantané de la figure comme c'est le cas avec Cabri. Il est donc exclu de pouvoir implémenter une fonction de recherche de lieux de points comme il en existe dans de nombreux logiciels. Par ailleurs, elle est moins précise qu'un calcul traditionnel de coordonnées. |
Il apparait évident que cette méthode de recherche graphique de points |
649 |
|
d'intersection est plus coûteuse en terme de complexité temporelle |
650 |
En revanche, cette méthode présente un véritable intéret pédagogique. Si un lycéen de terminal n'a nul besoin de voir apparaitre les taits de constructions d'un milieu, cela peut se révéler intéressant pour un élève de classe primaire apprenant le b.a ba de la géométrie. Ce type de visualisation permettrait aux plus jeunes de retrouver à l'écran ce qu'ils ont l'habitude de tracer sur papier. |
qu'une classique résolution d'équations. On ne peut ainsi obtenir un |
651 |
|
affichage quasi instantané de la figure comme c'est le cas avec |
652 |
|
Cabri. Il est donc exclu de pouvoir implémenter une fonction de |
653 |
|
recherche de lieux de points comme il en existe dans de nombreux |
654 |
|
logiciels. Par ailleurs, elle est moins précise qu'un calcul |
655 |
|
traditionnel de coordonnées. |
656 |
|
|
657 |
|
En revanche, cette méthode présente un véritable intéret |
658 |
|
pédagogique. Si un lycéen de terminal n'a nul besoin de voir |
659 |
|
apparaitre les taits de constructions d'un milieu, cela peut se |
660 |
|
révéler intéressant pour un élève de classe primaire apprenant le b.a |
661 |
|
ba de la géométrie. Ce type de visualisation permettrait aux plus |
662 |
|
jeunes de retrouver à l'écran ce qu'ils ont l'habitude de tracer sur |
663 |
|
papier. |
664 |
|
|
665 |
L'implémentation actuelle de cette méthode n'est pas parfaite et présente quelques défauts qu'il faudrait corriger à l'avenir : |
L'implémentation actuelle de cette méthode n'est pas parfaite et présente quelques défauts qu'il faudrait corriger à l'avenir : |
666 |
\begin{itemize} |
\begin{itemize} |
668 |
\item Manque de précision pour une construction dont les points sont très rapprochés. |
\item Manque de précision pour une construction dont les points sont très rapprochés. |
669 |
\item Pas d'affichage du nom des points. |
\item Pas d'affichage du nom des points. |
670 |
\item Encombrement de la fenêtre graphique pour des figures complexes. |
\item Encombrement de la fenêtre graphique pour des figures complexes. |
671 |
\item Obtention de figures particulières dûe à la génération aléatoire de points.\\ |
\item Obtention de figures particulières dûe à la génération aléatoire |
672 |
|
de points. |
673 |
|
|
674 |
Exemple: triangle applati, droites confondues, etc... |
Exemple: triangle applati, droites confondues, etc... |
675 |
\item etc ... |
\item etc ... |
676 |
\end{itemize} |
\end{itemize} |
677 |
|
|
678 |
\chapter{Sortie Postcript} |
\chapter{Sortie Postcript} |
679 |
|
\minitoc{} |
680 |
|
|
681 |
Lorsqu'on utilise un logiciel de dessin géométrique, il est intéressant que l'utilisateur puisse obtenir une sortie 'papier' de son travail. Plusieurs solutions sont alors envisageables. On peut tout d'abord communiquer avec l'imprimante via l'envoi de paquets d'octets. Cette méthode est très lourde au niveau réalisation et n'offre pas un résultat très satisfaisant. On peut aussi générer un fichier qui sera ensuite imprimé via des filtres existants et dont l'efficacité est bien éprouvée. Lorsqu'on parle d'impression, les fichiers les plus couramment utilisés sont les fichiers Postcript dont le format est très utilisé en imprimerie et très répandu dans le monde Unix. La plupart du temps la génération d'un fichier Postcript se fait par compilation d'un fichier \LaTeX{}. |
Lorsqu'on utilise un logiciel de dessin géométrique, il est |
682 |
|
intéressant que l'utilisateur puisse obtenir une sortie «papier» de |
683 |
Dessiner avec \LaTeX{} passe souvent par l'utilisation de la distribution PSTricks composée d'un ensemble de fonctions puissantes. Dominique Rodriguez a écrits à partir du dialect PSTriks l'extension \verb+pst-eucl.sty+ permettant de tracer avec plus ou moins de facilité des figures géométriques. Nous allons donc l'utiliser pour pouvoir à partir de notre structure d'arbre, générer une suite d'instructions de ce type: |
son travail. Plusieurs solutions sont alors envisageables. On peut |
684 |
|
tout d'abord communiquer avec l'imprimante via l'envoi de paquets |
685 |
|
d'octets. Cette méthode est très lourde au niveau réalisation et |
686 |
|
n'offre pas un résultat très satisfaisant. On peut aussi générer un |
687 |
|
fichier qui sera ensuite imprimé via des filtres existants et dont |
688 |
|
l'efficacité est bien éprouvée. Lorsqu'on parle d'impression, les |
689 |
|
fichiers les plus couramment utilisés sont les fichiers Postcript dont |
690 |
|
le format est très utilisé en imprimerie et très répandu dans le monde |
691 |
|
Unix. Souvent, la génération d'un fichier Postcript se fait |
692 |
|
par compilation d'un fichier \LaTeX{}. |
693 |
|
|
694 |
|
Dessiner avec \LaTeX{} passe souvent par l'utilisation de la |
695 |
|
distribution PSTricks composée d'un ensemble de fonctions |
696 |
|
puissantes. Dominique Rodriguez a écrits à partir du dialect PSTriks |
697 |
|
l'extension \verb+pst-eucl.sty+ permettant de tracer avec plus ou |
698 |
|
moins de facilité des figures géométriques. Nous allons donc |
699 |
|
l'utiliser pour pouvoir à partir de notre structure d'arbre, générer |
700 |
|
une suite d'instructions de ce type: |
701 |
|
|
702 |
\begin{verbatim} |
\begin{verbatim} |
703 |
pstGeonode(0,-1){A}\pstGeonode(3,2){B} |
\pstGeonode(0,-1){A}\pstGeonode(3,2){B} |
704 |
\pstGeonode(3,0){C}\pstGeonode(1,2){D} |
\pstGeonode(3,0){C}\pstGeonode(1,2){D} |
705 |
\pstInter[PointSymbol=pstSmallSquare]{A}{B}{C}{D}{E} |
\pstInter[PointSymbol=pstSmallSquare]{A}{B}{C}{D}{E} |
706 |
\psset{linecolor=blue, nodesep=-1} |
\psset{linecolor=blue, nodesep=-1} |
709 |
|
|
710 |
\section{Présentation rapide de l'extension pst-eucl} |
\section{Présentation rapide de l'extension pst-eucl} |
711 |
|
|
712 |
L'extension pst-eucl présente beaucoup de fonctions prédéfinies. Ici ne nous intéressent que les fonctions de traçage de points, de lignes, de cercles et d'intersections: |
L'extension pst-eucl présente beaucoup de fonctions prédéfinies. Ici |
713 |
|
ne nous intéressent que les fonctions de traçage de points, de lignes, |
714 |
|
de cercles et d'intersections: |
715 |
\begin{itemize} |
\begin{itemize} |
716 |
\item tracé d'un point: \verb+\pstGeonode+\textit{(x,y)}\verb+{+\textit{<nom du point>}\verb+}+ |
\item tracé d'un point: \verb+\pstGeonode+\textit{(x,y)}\verb+{+\textit{<nom du point>}\verb+}+ |
717 |
\item tracé d'une ligne: \verb+\pstLineAB+\verb+{+\textit{<nom du point1>}\verb+}+\verb+{+\textit{<nom du point2>}\verb+}+ |
\item tracé d'une ligne: \verb+\pstLineAB+\verb+{+\textit{<nom du point1>}\verb+}+\verb+{+\textit{<nom du point2>}\verb+}+ |
731 |
|
|
732 |
\section{Chaine de production du fichier} |
\section{Chaine de production du fichier} |
733 |
|
|
734 |
Il faut tout d'abord créer un fichier \LaTeX{}. Ici encore tout se résume à un parcours postfixé d'arbres. Bien qu'un peu plus compliqué que celui décrit au chapitre 2, il en reprend les grandes lignes. A savoir une analyse du noeud courant suivant son type: point quelconque, droite, cercle, point d'intersection (cf Annexe). Ici aussi, on génère des coordonnées aléatoirement lorsqu'il s'agity d'afficher un point quelconque. Cela implique que l'utilisateur peut obtenir pour un même arbre plusieurs dessins différents. |
Il faut tout d'abord créer un fichier \LaTeX{}. Ici encore tout se |
735 |
|
résume à un parcours postfixé d'arbres. Bien qu'un peu plus compliqué |
736 |
Une fois que l'on a obtenu notre fichier \LaTeX{}, on le compile en un fichier DVI. Cette opération est effectuée automatiquement afin de simplifier la vie à l'utilsateur. On fait alors appel à la bibliothèque \verb+Sys+ de Caml: |
que celui décrit au chapitre 2, il en reprend les grandes lignes. À |
737 |
|
savoir une analyse du noeud courant suivant son type: point |
738 |
|
quelconque, droite, cercle, point d'intersection (cf Annexe). Ici |
739 |
|
aussi, on génère des coordonnées aléatoirement lorsqu'il s'agity |
740 |
|
d'afficher un point quelconque. Cela implique que l'utilisateur peut |
741 |
|
obtenir pour un même arbre plusieurs dessins différents. |
742 |
|
|
743 |
|
Une fois que l'on a obtenu notre fichier \LaTeX{}, on le compile en un |
744 |
|
fichier DVI. Cette opération est effectuée automatiquement afin de |
745 |
|
simplifier la vie à l'utilsateur. On fait alors appel à la |
746 |
|
bibliothèque \verb+Sys+ de Caml: |
747 |
\begin{verbatim} |
\begin{verbatim} |
748 |
let create_dvi source = |
let create_dvi source = |
749 |
Sys.command ("latex "^source);() |
Sys.command ("latex "^source);() |
|
|
|
750 |
\end{verbatim} |
\end{verbatim} |
751 |
A partir du fichier DVI, l'obtention du fichier Postcript se fait grâce à la fonction: |
|
752 |
|
À partir du fichier DVI, l'obtention du fichier Postcript se fait grâce à la fonction: |
753 |
\begin{verbatim} |
\begin{verbatim} |
754 |
let create_ps source = |
let create_ps source = |
755 |
Sys.command ("dvips "^source^" -o");() |
Sys.command ("dvips "^source^" -o");() |
|
|
|
756 |
\end{verbatim} |
\end{verbatim} |
757 |
|
|
758 |
\chapter{Un parser pour l'utilisateur} |
\chapter{Un language pour l'utilisateur} |
759 |
|
\minitoc{} |
760 |
|
|
761 |
Comme nous l'avons précisé en introduction, l'utilisation du programme doit se faire via un langage dédié. L'utilisateur doit taper dans un éditeur quelconque un texte décrivant sa figure qui sera ensuite interprété par le programme. Pour des raisons de simplicité nous avons choisi d'implémenter un langage se rapprochant le plus possible des notations et tournures employées dans les exercices de géométrie. |
Comme nous l'avons précisé en introduction, l'utilisation du programme |
762 |
|
doit se faire via un langage dédié. L'utilisateur doit saisir dans un |
763 |
Les outils utilisés dans ce chapitre sont ocamllex et ocamlyacc, construits pour le Caml sur le modèle de lex et yacc dédié pour le langage C. |
éditeur quelconque un texte décrivant sa figure qui sera ensuite |
764 |
|
interprété par le programme. Pour des raisons de simplicité nous avons |
765 |
|
choisi d'implémenter un langage se rapprochant le plus possible des |
766 |
|
notations et tournures employées dans les exercices de géométrie. |
767 |
|
|
768 |
|
Les outils utilisés dans ce chapitre sont ocamllex et ocamlyacc, |
769 |
|
construits pour le Caml sur le modèle de lex et yacc dédié pour le |
770 |
|
langage C. |
771 |
|
|
772 |
\section{Description du langage} |
\section{Description du langage} |
773 |
|
|
774 |
Le langage implanté est déclaratif. Toutes commandes commencent par \verb+soit+ ou \verb+Soit+. Il faut ensuite indiquer la nature de l'objet à construire: un point, une droite ou un cercle. L'article qui précède le type de l'objet n'a pas d'importance, on peut aussi bien écrire \verb+un point+ que \verb+le point+. Un nom doit figurer après la déclaration de la nature de l'objet. Nous attirons l'attention sur le fait que le nom d'un objet doit toujours être en majuscule. |
Le langage implanté est déclaratif. Toutes commandes commencent par |
775 |
|
\verb+soit+ ou \verb+Soit+. Il faut ensuite indiquer la nature de |
776 |
|
l'objet à construire: un point, une droite ou un cercle. L'article qui |
777 |
|
précède le type de l'objet n'a pas d'importance, on peut aussi bien |
778 |
|
écrire \verb+un point+ que \verb+le point+. Un nom doit figurer après |
779 |
|
la déclaration de la nature de l'objet. Nous attirons l'attention sur |
780 |
|
le fait que le nom d'un objet doit toujours être en majuscule. |
781 |
|
|
782 |
|
Après le nom de l'objet vient la manière dont il doit être |
783 |
|
construit. Différentes constructions existent suivant le type de |
784 |
|
l'objet. |
785 |
|
|
|
Après le nom de l'objet vient la manière dont il doit être construit. Différentes constructions existent suivant le type de l'objet. \\ |
|
786 |
\underline{Pour un point:} |
\underline{Pour un point:} |
787 |
\begin{itemize} |
\begin{itemize} |
788 |
\item quelconque: on utilise le mot \verb+quelconque+ |
\item quelconque: on utilise le mot \verb+quelconque+ |
839 |
|
|
840 |
\section{L'analyse lexicale} |
\section{L'analyse lexicale} |
841 |
|
|
842 |
On utilise ici ocamllex pour générer un fichier source qui doit réaliser un traitement lexicographique du texte source en y reconnaisant des expressions régulières. A chaque expression reconnue, on retourne le constructeur correspondant. |
On utilise ici ocamllex pour générer un fichier source qui doit |
843 |
|
réaliser un traitement lexicographique du texte source en y |
844 |
|
reconnaisant des expressions régulières. À chaque expression reconnue, |
845 |
|
on retourne le constructeur correspondant. |
846 |
|
|
847 |
\begin{verbatim} |
\begin{verbatim} |
848 |
{ |
{ |
887 |
|
|
888 |
\section{Analyse syntaxique} |
\section{Analyse syntaxique} |
889 |
|
|
890 |
Constrairement à l'analyse lexicale nous allons ici nous attacher à reconnaitre la structure grammaticale de la commande tapée par l'utilisateur. Pour cela nous devons définir la grammaire de notre langage: \\ |
Constrairement à l'analyse lexicale nous allons ici nous attacher à |
891 |
|
reconnaitre la structure grammaticale de la commande tapée par |
892 |
|
l'utilisateur. Pour cela nous devons définir la grammaire de notre |
893 |
|
langage: |
894 |
|
|
895 |
$axiome \rightarrow UN \ POINT \ IDENTIFIANT \ r1 \\$ |
$axiome \rightarrow UN \ POINT \ IDENTIFIANT \ r1 \\$ |
896 |
$| UNE \ DROITE \ IDENTIFIANT r2 \\$ |
$| UNE \ DROITE \ IDENTIFIANT r2 \\$ |
930 |
$| DE \ CENTRE \ o2 \ ET \ DE \ RAYON \ IDENTIFIANT \\$ |
$| DE \ CENTRE \ o2 \ ET \ DE \ RAYON \ IDENTIFIANT \\$ |
931 |
|
|
932 |
\chapter{Installation et utilisation} |
\chapter{Installation et utilisation} |
933 |
|
\minitoc{} |
934 |
|
|
935 |
\section{Configuration nécessaire et installation} |
\section{Configuration nécessaire et installation} |
936 |
|
|
937 |
Il est conseillé d'utiliser ce programme sous un sytème Unix (Linux, Solaris, ...) disposant d'un compilateur Caml (au minimum la version 3.00). Toutefois, une utlisation sous Windows devrait en théorie être possible... \\ |
Il est conseillé d'utiliser ce programme sous un sytème Unix (Linux, Solaris, ...) disposant d'un compilateur Caml (au minimum la version 3.00). Toutefois, une utlisation sous Windows devrait en théorie être possible... |
938 |
|
|
939 |
Pour pouvoir générer les fichiers Postcript, il faut installer l'extension pst-eucl de Dominique RODRIGUEZ. Sous Linux, la procédure est la suivante: |
Pour pouvoir générer les fichiers Postcript, il faut installer l'extension pst-eucl de Dominique RODRIGUEZ. Sous Linux, la procédure est la suivante: |
940 |
\begin{itemize} |
\begin{itemize} |
941 |
\item copier pst-eucl.pro dans /usr/share/texmf/dvips/pstricks |
\item copier pst-eucl.pro dans /usr/share/texmf/dvips/pstricks |
942 |
\item copier les fichiers pst-eucl.tex et pst-eucl.sty dans \\ |
\item copier les fichiers pst-eucl.tex et pst-eucl.sty dans |
943 |
/usr/share/texmf/tex/generic/pstricks |
/usr/share/texmf/tex/generic/pstricks |
944 |
\item dans une console taper \verb+texhash+ \\ |
\item dans une console taper \verb+texhash+ |
945 |
\end{itemize} |
\end{itemize} |
946 |
|
|
947 |
L'installation du programme lui-même est simplifiée par l'utilisation d'un Makefile. Il suffit donc d'ouvrir une console et taper: |
L'installation du programme lui-même est simplifiée par l'utilisation |
948 |
|
d'un Makefile. Il suffit donc d'ouvrir une console et taper: |
949 |
\begin{itemize} |
\begin{itemize} |
950 |
\item \verb+make depend+ |
\item \verb+make depend+ |
951 |
\item puis \verb+make bc+ pour compiler en byte-code et obtenir l'exécutable \verb+euclidebc+ (nécessite ocamlrun) |
\item puis \verb+make bc+ pour compiler en byte-code et obtenir |
952 |
\item ou \verb+make opt+ pour compiler en natif et obtenir l'exécutable \verb+euclideopt+ |
l'exécutable \verb+euclidebc+ (nécessite ocamlrun) |
953 |
|
\item ou \verb+make opt+ pour compiler en natif et obtenir |
954 |
|
l'exécutable \verb+euclideopt+ |
955 |
\end{itemize} |
\end{itemize} |
956 |
|
|
957 |
\section{Principe d'utilisation} |
\section{Principe d'utilisation} |
958 |
|
|
959 |
L'utilisateur doit commencer par taper son fichier source dans un éditeur de texte quelconque (Emacs par exemple) et l'enregistrer en un \verb+.eu+ (\verb+essai.eu+ par exemple). Ensuite, dans une console il doit taper:\\ |
L'utilisateur doit commencer par taper son fichier source dans un |
960 |
|
éditeur de texte quelconque (Emacs par exemple) et l'enregistrer en un |
961 |
|
\verb+.eu+ (\verb+essai.eu+ par exemple). Ensuite, dans une console il |
962 |
|
doit taper: |
963 |
|
|
964 |
\begin{itemize} |
\begin{itemize} |
965 |
\item \verb+./euclidebc essai.eu -ps+ pour générer le fichier essai.eu.ps qui peut ensuite être imprimé ou visualisé via un logiciel comme GhostView. |
\item \verb+./euclidebc essai.eu -ps+ pour générer le fichier |
966 |
\item ou \verb+./euclideopt essai.eu -gr+ pour obtenir une visualisation dans la fenêtre graphique du Caml. |
essai.eu.ps qui peut ensuite être imprimé ou visualisé via un |
967 |
|
logiciel comme GhostView. |
968 |
|
\item ou \verb+./euclideopt essai.eu -gr+ pour obtenir une |
969 |
|
visualisation dans la fenêtre graphique du Caml. |
970 |
\end{itemize} |
\end{itemize} |
971 |
|
|
972 |
\chapter{Conclusion} |
\chapter{Conclusion} |
991 |
|
|
992 |
Pour terminer évoquons une possibilité d'extension du programme par |
Pour terminer évoquons une possibilité d'extension du programme par |
993 |
l'ajout d'un système expert démonstrateur. En effet, la géométrie ne |
l'ajout d'un système expert démonstrateur. En effet, la géométrie ne |
994 |
se résume pas qu'au traçage de figures, elle tend aussi à démontrer |
se résume pas qu'au tracer de figures, elle tend aussi à démontrer |
995 |
des propriétés sur ces mêmes figures. Or la plupart des logiciels du |
des propriétés sur ces mêmes figures. Or la plupart des logiciels du |
996 |
type Cabri, ne permettent pas de générer des démonstrations |
type Cabri, ne permettent pas de générer des démonstrations |
997 |
automatiques pour un problème donné. |
automatiques ou même interactives pour un problème donné. |
998 |
|
|
999 |
Un démonstrateur repose avant tout sur une bonne représentation des |
Un démonstrateur repose avant tout sur une bonne représentation des |
1000 |
connaissances et un choix judicieux des objets de base. Ainsi le |
connaissances et un choix judicieux des objets de base. Ainsi le |