La tortue

De $1

Reprenez la tortue que vous avez construite au TP 2.

Tracer les mouvements de la tortue

Les commandes

Pour qu'on puisse la dessiner la tortue doit enregistrer les ordres qu'on lui a donnés et les reproduire graphiquement.

Proposer une interface (ou une classe abstraite) Command qui sera commune à toutes les commandes.

La première commande est:

  1. DrawLine qui trace une ligne entre 2 points. 

Modifier la Tortue créée au TP2 pour produire une liste de commandes lors des déplacements de la tortue. La liste de commandes sera la trace laissée par la tortue.

Vous pourrez ensuite ajouter une commande ChangeColor qui permet de changer la couleur du pinceau utilisé par la tortue.

Log

Pour tester votre tortue, vous utiliserez une classe Log qui affiche dans un PrintWriter la trace laissée par une tortue. On testera en écrivant sur la console ou dans un fichier.

Applet

Au lieu de tracer dans un fichier les mouvements de la tortue, produire une Applet qui affiche à l'écran le résultat produit par la commande. Par exemple, on pourra ajouter une méthode paint(...) à l'interface Command. Quelle doit être sa signature ? 

Les comportements

La tortue ivre

Réaliser un comportement tortue ivre qui déplace une tortue de façon aléatoire. A chaque pas, la tortue tourne d'un angle aléatoire et avance d'une distance aléatoire non nulle.

Dans un second temps, pour donner un peu plus de réalisme, on limitera l'angle de rotation à des valeurs comprises entre -10° et +10°.

Les formes géométriques

Ecrire un comportement qui fait dessiner un carré à une tortue. On donnera en paramètre la longueur du côté du carré. 

Ajouter un autre comportement qui dessine d'autres types de polygones (pas seuleument des carrés): par exemple des polygones à n côtés de longueur dn et d sont les paramètres.

La poursuite

Créer un comportement de poursuite pour une tortue. Une tortue poursuit une autre tortue. Son algorithme est simple. A chaque pas, la tortue se tourne en direction de la tortue à poursuivre et avance d'un pas. La tortue poursuivante ne va pas nécessairement plus vite que la tortue que l'on poursuit.

Tester votre comportement en poursuivant une tortue ivre et compter le nombre de pas nécessaires pour rattraper la tortue que l'on poursuit. Faire varier la vitesse relative de la tortue poursuivante par rapport à la vitesse de la tortue poursuivie.

Le flocon de Von Koch

Le flocon de Von Koch est une courbe fractale qui est assez délicate à construire en coordonnées absolues mais assez facile à construire par récurrence en utilisant une tortue.

La définition récursive de la courbe de Von Koch est la suivante:

courbe(int n, double d):

  • si n==0 alors avancer de d

  • si n>0 alors

    • courbe(n-1, d/3)

    • tourner à gauche de 60°
    • courbe(n-1, d/3)
    • tourner à droite de 120°
    • courbe(n-1, d/3)
    • tourner à gauche de 60°
    • courbe(n-1, d/3)

On remarquera qu'on a tourné au total de 0°, c'est essentiel pour réussir une figure fractale récursive !

On remarquera également que courbe(1,d) positionne la tortue à une distance de d par rapport à l'origine alors qu'on a fait 4 tracés de distance d/3 (d'où la notion de fractale avec une dimension 4/3).

A vous de la traduire en Java avec votre tortue. 

Une fois qu'on sait faire la courbe, faire une flocon est une formalité. Sa définition (non récursive) est la suivante:

flocon(int n, double d):

  • courbe(n, d)
  • tourne à droite de 120°
  • courbe(n, d)
  • tourne à droite de 120°
  • courbe(n, d)
  • tourne à droite de 120°

Que se passe-t-il si on tourne à gauche au lieu de à droite ?

Les éponges de Menger

On voudrait maintenant que notre tortue puisse dessiner des formes géométriques remplies. 

On va donc ajouter deux opérations à notre tortue (avec les commandes nécessaires):

  • débuteFigurePleine() : détermine que chacune des positions suivantes doit être enregistrée
  • termineFigurePleine() : utilise l'ensemble des positions enregistrées depuis le dernier appel de débuteFigurePleine pour faire un Polygon rempli avec la couleur courante. On pourra par exemple utiliser la méthode fillPolygon de la classe Graphics.

Tester vos nouvelles opérations pour dessiner un polygône plein.

Utiliser cette fonctionnalité pour réaliser une éponge de Menger.

Peu importe la définition mathématique, la définition récursive est la suivante:

eponge(int n, double d):

  • si (n==0) faire un carré plein (coloré) de côté d
  • si (n>0) alors
    • se positionner pour dessiner le carré supérieur gauche
    • eponge(n-1, d/3)
    • se déplacer latéralement de d/3 (sans marquer et sans changer de direction)
    • eponge(n-1, d/3)
    • se déplacer latéralement de d/3 (sans marquer et sans changer de direction)
    • eponge(n-1, d/3)
    • se déplacer latéralement de -2d/3 et verticalement de d/3 (sans marquer et sans changer de direction)
    • eponge(n-1, d/3)
    • se déplacer latéralement de 2d/3 (sans marquer et sans changer de direction)
    • eponge(n-1, d/3)
    • se déplacer latéralement de -2d/3 et verticalement de d/3 (sans marquer et sans changer de direction)
    • eponge(n-1, d/3)
    • se déplacer latéralement de d/3 (sans marquer et sans changer de direction)
    • eponge(n-1, d/3)
    • se déplacer latéralement de d/3 (sans marquer et sans changer de direction)
    • eponge(n-1, d/3)
    • se repositionner à la position initiale

 Noter qu'il y a seulement 8 appels récursifs (et pas 9).