DESS IDC
Introduction à la programmation orientée objet
Le langage JAVA

De l'algo en JAVA ?
Du logo en JAVA ?




Dernière modification : 16 février 1999, Philippe Genoud

Le thème de cette semaine consiste à réaliser des actions récursives (thème actuel du cours et des TD d'algorithmique). Plus précisément il s'agit d'écrire les programmes JAVA correspondant aux exercices de tracés de figures géométrique proposés dans le chapitre 8 (Actions récursives) du cours d'algorithmique de Pierre-Claude Scholl.

Bien que ce thème relève plus du cours d'algorithmique que du cours de programmation orientée objet, nous allons en profiter pour expérimenter avec les packages.

Pour réaliser ces exercices vous disposez de trois classes définies dans un package de nom pg.coursjava.logo. Ce package comme son nom l'indique permet de faire en JAVA du dessin à la "Logo". Logo est un langage destiné à apprendre de manière ludique la programmation. Pour cela le langage Logo permet de manipuler une "tortue" qui est très similaire à  la plume de la machine de tracés définie dans le cours d'algorithmique.

Ce package regroupe trois classes :

- une classe Pt qui permet de définir des points.
- une classe Fenetre qui permet de gérer la fenêtre de tracé.
- une classe Plume qui permet de gérer la plume dans la fenêtre de tracé.

Si vous voulez consulter les sources de ces classes : Pt.java, Fenetre.java, Plume.java

Pour réaliser ce Tp deux solutions sont envisageables :

- écrire un programme (une classe) ne comportant que des méthodes statiques : Carres.java
- étendre la classe Plume (par héritage) en lui ajoutant des méthodes de tracé de plus haut niveau (qui bien sûr peuvent être récursives) : Carres2.java

Lisez ces programmes et adoptez la stratégie qui vous convient le mieux. Personnellement je préfère la deuxième qui relève plus d'une approche orientée objet.

Bien sûr pour pouvoir compiler ces classes il faut que vous indiquiez dans votre classpath le chemin d'accès aux classes du package pg.coursjava.logo.

Deux solution se présentent :

a) Recompiler le package pg.coursjava.logo

  1. créez chez vous une hiérarchie de répertoires sources/pg/coursjava/logo et recopier dans le répertoire logo les fichier sources des différentes classes du package.
  2. créez chez vous un répertoire classes qui vous servira à ranger vos .class et les packages que vous écrirez ou que vous ramènerez .
  3. placez vous dans le répertoire sources
  4. compilez les classes du package pg.coursjava.logo par la commande

  5. javac "-d ..../classes" pg/coursjava/logo/Fenetre.java
    qui a pour effet de placer les fichiers .class dans le répertoire indiqué par l'option -d et où ..../classes est le chemin d'accès à la racine des répertoires correspondants aux packages. (vous constaterez qu'une hierarchie de répertoires respectant le nom du package a été créée dans le répertoire classes)
  6. par la suite il faudra indiquer comme classpath lorsque vous compilerez vos nouveaux programmes :

  7. .   le répertoire courant
    ..../classes  le chemin d'accès à la racine des répertoires correspondants aux packages.
b) Utiliser un fichier archive (jar) contenant déjà toutes les classes compilés du package pg.coursjava.log
  1. recopiez chez vous le fichier logo.jar(en cliquant sur le bouton droit de la souris et en sélectionnant l'item enregistrer le lien sous du menu qui apparait alors. Si vous le souhaitez vous pourrez faire la commande jar -tvf logo.jar pour voir son contenu).
  2. n'oubliez pas ensuite d'intégrer ce fichier jar à votre classpath pour compiler vos classes utilisant les classes de ce package (vous vous reporterez pour cela au Tp visages1).
Travail à faire :

1) après avoir installé le package, compiler et exécuter les programmes exemples Carre.java et Carre2.java.

2) écrire les actions récursives correspondant aux exercices du cours d'algorithmique dont vous trouverez dans ce qui suit une version html.
(le cours et les images ont été scannés d'où une mauvaise qualité des images et peut être encore quelques erreurs dues à la mauvaise précision du programme d'OCR ... et à ma fatigue pour relire tout cela).



UJF-UFR IMA- DESS IDC Algorithmique exemples et exercices
Cours d'algorithmique de PC-SCHOLL
extraits de "Cours d'informatique, langages et programmation", P.C. Scholl, M.C. Fauvet, F. Lagnier et  F. Maraninchi, Masson décembre 1993.

Tracé de carrés emboîtés

Contexte : une machine de tracés

(Cf. [SP88], pp38, 39)

Nous définissons une machine-tracés, c'est-à-dire un répertoire de primitives élémentaires de tracés. Nous l'utilisons pour illustrer la notion d'action, le raisonnement sur les états et les diverses formes de composition d'actions.

description de l'état de lamachine

L'état de la machine-tracés est caractérisé par l'état de deux composants : l'écran et la plume de tracé. L'écran est un ensemble de points qui peuvent être éteints ou allumés. Une figure est matérialisée par des points allumés. Les points sont désignés à l'aide de coordonnées définies dans un système d'axes Ox, Oy dont l'origine, nommée centre (de l'écran) appartient au lexique de la machine-tracés. Un état de l'écran, c'est-à-dire son état à un instant donné, est caractérisé par les figures qu'il comporte. L'état particulier dans lequel tous les points sont éteints est nommé écran vide. Lorsque nous voulons indiquer qu'aucune contrainte particulière n'est imposée à l'écran, nous disons qu'il est dans un état indifférent.

La machine-tracés manipule une plume dont l'état est défini par trois attributs :

Lorsque nous voulons indiquer qu'aucune propriété particulière n'est attachée à l'état de la plume ou à l'un de ses attributs, nous disons qu'elle est dans un état ind~ifférent ou que tel attribut a une valeur indifférente.

Les primitives du répertoire sont regroupées selon le type de modifications qu'elles apportent à l'état de l'écran ou de la plume.

modification globale de l'écran etdela plume
 

modification de la position d'écrituredela plume
  modification de la position de laplumedans le plan
  Les trois primitives Avancer, Reculer et Placer modifient la position de la plume, même si la plume est haute. Elles provoquent un tracé dès que la plume est basse : elles modifient donc l'état de l'écran dans ce cas. Elles ne modifient jamais la position d'écriture ni le cap de la plume.

modification du cap de la plume

Exemple E8.2 : Tracé de carrés emboîtés

Définir une action de tracé permettant de tracer une figure formée de n carrés emboités (n=4 sur la figure 8. 1). La figure doit être tracée sans lever la plume et sans tracer deux fois le même trait. On peut toutefois passer plusieurs fois par le même point.


Figure 8.1: 4 carrés emboîtés à tracer sans lever la plume

Une telle figure est définie par le nombre de carrés emboîtés et son carré extérieur. On convient ici qu'un carré est défini par son sommet, sa taille et son cap : le sommet du carré est l'un de ses sommets ; la taille du carré est la taille de ses côtés ; le cap du carré est le cap du côté passant par le sommet tel qu'un observateur placé sur ce sommet et regardant dans le sens de ce côté, voit tous les autres côtés à sa gauche et devant lui .

Ainsi une figure est donnée par son ordre (nombre de carrés emboîtés), son sommet (sommet du carré extérieur), sa taille (taille du carré extérieur) et son cap (cap du carré extérieur).

On spécifie l'action Tcaremb, de tracé de carrés emboîtés :

Tcaremb : une action (les données : un entier > O, un réel > 0) { Tcaremb (n, t) trace sans lever la plume et sans tracer deux fois le même trait, une figure de n carrés emboîtés et de taille t :

état initial : plume basse au sommet de la figure et au cap de la figure.

état final : figure tracée, plume dans I'état initial }

On définit l'ensemble des figures de manière récurrente

Figure 8.2: Une figure d'ordre n +1 est constituée d'un carré et d'une figure d'ordre n.

Pour tenir compte de la contrainte de tracé, on décompose le carré extérieur en deux parties délimitées par l'un des points communs au carré extérieur et à la figure intérieure. On décompose ainsi le tracé d'un carré en deux actions intermédiaires de tracé : TDébutCar et TFinCarde telle sorte que

Tcarré (t) : TDébutCar (t) ; TFinCar (t)

Tdébutcar : une action (la donnée : un réel >O)

{ trace le début d'un carré de taille donnée :
Etat initial : plume basse au sommet du carré, orientée selon le cap du carré
Etat final : fin du carré tracé, plume basse au milieu d'un côté et au cap de ce côté }
Tfincar : une action (la donnée un réel >O) { trace la fin d'un carré de taille donnée :
Etat initial : plume basse au milieu du côté d'un carré, orientée selon le cap de ce côté
Etat final : fin du carré tracée, plume basse au sommet dzl carré et au cap du carré }
En choisissant comme point intermédiaire le milieu du premier côté du carré, on obtient :

Tdébutcar (t) : Av (t/2)

Tfincar (t) :

Av (t/2) ; TrG (90)
i parcourant [1...3] : Av (t) ; TrG (90)
On peut maintenant donner une réalisation récursive de l'action Tcaremb, s'appuyant sur la définition récurrente de la figure :

Tcaremb (n, t)
{ plume basse au sommet et au cap de la figure }

si n 1 alors
Tdébutcar (t) ; Tfincar (t) sinon Tdébutcar (t)

TrG (45)

{ plume basse au milieu du côté, au cap de la figure intérieure }

Tcaremb (n-l, t / rac(2) )

{ figure intérieure tracée, plume basse à son sommet et à son cap } TrD (45)

Tfincar (t)

{ figure tracée, pl2lme dans le même état qu'au départ }
Par exemple l'algorithme Vider ; Baisser ; Tcaremb (10, 4) trace une figure d'ordre 10 de sommet le centre de l'écran, de taille 4 et de cap OuestEst.

Dessins récursifs

E8.5 : Trace de I'exécution d'uneactionrécursive

Observer l'exécution de l'action récursive Tcaremb de tracé de carrés emboités :

Donner la trace de l'exécution de l'algorithme Vider ; Baisser ; Tcaremb (4, 4) sous forme de la liste des appels engendrés, mise en page avec une indentation reflétant la structure emboîtée des appels récursifs (Cf. 8.A.a).

E8.6 : Arbres binaires

Ecrire une action de tracé d'un arbre binaire. Les données sont la profondeur de l'arbre et le point origine, la taille et le cap du tronc. Par exemple, pour une profondeur 5, et un troncd'origine 0, de taille 3 orienté dans le sens OuestEst, on obtient le dessin de la figure 8.3.


Figure 8.3: Arbre binaire de profondeur 5

E8.7 : Flocons

Définir une action de tracé de dessins de la famille donnée par la figure 8.4. Les données sont la taille du trait élémentaire et le nombre de niveaux.

E8.8 : Etoiles

L'objet de cet exercice est de construire un algorithme de tracé d'un dessin récursif formé d'étoiles à cinq branches, comme l'illustrent les deux figures 8.5 et 8.6.


Figure 8.5: Etoiles à cinq branches

Q1) Tracé d'une étoile à cinq branches

On veut tracer une étoile à cinq branches comme celle de la figure 8.5. Une telle étoile est caractérisée par :

TracerUneEtoile : une action (la donnée : un réel) { S et C étant respectivement la position et le cap de la plume à l?appel de l?action TracerUneEtoile(T) trace une étoile de taille T, de sommet S et de cap C )

TracerUneEtoile (T)

I parcourant [1..5]

Avancer (T) ; TournerDroite (A)

Q2) Une explosion d'étoiles

On veut maintenant tracer les dessins récursifs composés d'étoiles comme ceux donnés dans la figure 8.6.

 

Figure 8.6: Tracé d'étoiles récursif Un tel dessin est caractérisé par :

- son ordre, comme le suggèrent les figures : la figure d'ordre I comporte une étoile, la figure d'ordre 2 comporte une étoile de taille T et cinq étoiles de taille T/3, placées à chacun de ses sommets, ...

Spécifier et donner une réalisation récursive d'une action nommée TracéDEtoiles permettant de

tracer le dessin de taille T et d'ordre n, sachant qu'à l'état initial, la position dans le plan et le cap de la plume sont respectivement le sommet et le cap du dessin que l'on veut tracer.

E8.9 : Tricot (suite)

On considère un triangle équilatéral pavé de triangles équilatéraux élémentaires (figure 8.7). Le dessin est caractérisé par un sommet du triangle extérieur, un cap, la taille du coté du triangle extérieur et le nombre n de divisions en traits élémentaires du côté du triangle extérieur (n est une puissance de 2).

On spécifie l'action Ttriangles :

Ttriangles: une action (les données : un entier > O, un réel) { Ttriangles (n, T) trace la figure d'ordre n avec T pour taille du triangle extérieur.

Etat initial : plume basse au sommet du triangle extérieur orientée selon le cap, du triangle extérieur.

Etat final : figure tracée et plume dans l'état initial. }

Donner une réalisation récursive de Ttriangles, qui réalise le tracé sans lever la plume et sans passer deux fois par le même trait.

Figure 8.7: Triangles équilatéraux

Indications :

On peut envisager deux solutions :

- On décompose la figure en distinguant deux des côtés du triangle extérieur. Ces deux segments ne font pas partie de l'analyse récurrente. La figure intérieure restante doit être analysée récursivement. On peut y voir 4 objets numérotés 1, 2, 3 et 4, et un segment numéroté 5, comme suggéré figure 8.8. Les quatre objets 1, 2, 3, et 4 peuvent être tracés par une action récursive intermédiaire que l'on spécifiera.

- On décompose la figure en distinguant le triangle extérieur et l'intérieur de la figure. La figure intérieure doit être analysée récursivement. On peut la voir comme suggéré figure 8.9.


Figure 8.8: Triangles équilatéraux: indications pour le tracé récursif,solution1

Figure 8.9: Triangles équilatéraux: indications pour le tracé récursif,solution2