Programmation en Scala : un peu de graphique

mardi 6 mars 2018
par  Emmanuel Adam
popularité : 2%

Dessin d’une rosace

En supposant :

    • que la méthode line(x0,y0, x1,y1) existe et qu’elle trace une ligne entre les poins (x0, y0) et (x1, y1)
    • que le point (0,0) se situe en haut à gauche de la fenêtre,

il s’agit de tracer une rosace comme celle ci-dessous :

rosace
image de rosace réalisée en Scala

Nous allons utiliser la bibliothèque JavaFX.
Avec JavaFX, il faut créer les éléments graphiques pour les déposer sur un panneau (Pane)
Si root est la racine du panneau qui a une taille de (cote x cote) pixels, pour tracer une diagonale de haut à gauche en bas à droite, on écrira :

  1. var l1:Line = new Line(0,0 , cote,cote)
  2. root.getChildren.addAll(l1);

Pour dessiner la rosace, il est possible de déposer des séries de 4 lignes :

  1. //dessine une rosace sur le panneau dont la racine est 'roor'
  2. // trace nbPoints lignes par côté*/
  3. def dessineRosace(nbPoints:Int, root:Pane)
  4. {
  5.   var l1,l2,l3,l4:Line= null
  6.   var marge = cote/nbPoints
  7.   for (i<-0 to cote by marge)
  8.   {
  9.     l1 = new Line(i,0 , cote,i)
  10.     l2 = new Line(cote,i, cote-i,cote )
  11.     l3 = new Line(cote-i,cote , 0,cote-i)
  12.     l4 = new Line(0,cote-i, i,0)
  13.     root.getChildren.addAll(l1,l2, l3, l4);
  14.   }
  15. }

afficher une fenêtre en Scala

On utilise ici une fenêtre JavaFX qu’il faudra appeler.
Supposons que TestRosace soit le nom de l’application javafx, pour l’appeler, on passera par un objet qui contient la méthode principale main

  1. object Rosace {
  2.   def main(args: Array[String]): Unit = {
  3.     Application.launch(classOf[TestRosace], args: _*)
  4.   }
  5. }

Dans le même fichier, on écrira :

  1. class TestRosace extends javafx.application.Application {
  2.   val cote = 600
  3.  
  4.   def dessineRosace(nbPoints:Int, root:Pane) {
  5.     var l1,l2,l3,l4:Line= null
  6.     var marge = cote/nbPoints
  7.     for (i<-0 to cote by marge)
  8.     {
  9.       l1 = new Line(i,0 , cote,i)
  10.       l2 = new Line(cote,i, cote-i,cote )
  11.       l3 = new Line(cote-i,cote , 0,cote-i)
  12.       l4 = new Line(0,cote-i, i,0)
  13.       root.getChildren.addAll(l1,l2, l3, l4);
  14.     }
  15.   }
  16.  
  17.   override def start(primaryStage: Stage): Unit = {
  18.     primaryStage.setTitle("Rosace");
  19.     val root = new Pane()
  20.     primaryStage.setScene(new Scene(root, cote, cote))
  21.     primaryStage.show()
  22.     //ici on appelle la fonction qui dessine sur le 'root'
  23.     dessineRosace(100, root)
  24.   }
  25. }

On précise les importations de classes en tête de ce fichier :

  1. import javafx.application.Application
  2. import javafx.scene.Scene
  3. import javafx.scene.layout.Pane
  4. import javafx.scene.shape.Line
  5. import javafx.stage.Stage

Vous trouverez ci dessous le fichier complet à télécharger...

Petit exercice : poursuite de points

En reprenant le code précédant, on désire maintenant tracer des lignes entre des points qui se déplacent sur la fenêtre...
On définit la classe Point ainsi :

  1. class Point(var x:Int=0, var y:Int = 0);

Des points sont placés dans un tableau. A chaque étape :

    • une ligne est tracée entre chaque point et son suivant dans le tableau (pour le dernier point une ligne est tracée entre celui-ci et le premier point)
    • un déplacement est effectué entre chaque point et son suivant dans le tableau (le dernier point se déplace vers le premier)
      Pour se déplacer, un point avance de x% de la distance qui le sépare de son suivant dans le tableau.

La figure suivante est un exemple de résultat :

rosace 2
rosace obtenue à partir de 8 points se poursuivant

Ce résultat est obtenu à partir de 8 points répartis ainsi initialement :

  1. var tapPoints:Array[Point] = Array.ofDim(8);
  2. tapPoints(0) = new Point(0,20)
  3. tapPoints(1) = new Point(cote/2,cote/5)
  4. tapPoints(2) = new Point(cote,20)
  5. tapPoints(3) = new Point(4*cote/5,cote/2)
  6. tapPoints(4) = new Point(cote,cote)
  7. tapPoints(5) = new Point(cote/2,4*cote/5)
  8. tapPoints(6) = new Point(0,cote)
  9. tapPoints(7) = new Point(cote/5,cote/2)

Documents joints

code scala pour le dessin de rosace
code scala dessinant une rosace dans une fenêtre