LOCODUINO

Forum de discussion
Dépôt GIT Locoduino
Flux RSS

mercredi 14 novembre 2018

75 visiteurs en ce moment

TCOs en Processing (2)

. Par : Pierre59

Dans l’article précédent (TCOs en Processing) nous avons fabriqué pratiquement tous les pavés nécessaires pour faire des dessins de réseaux. Pour réaliser des TCOs il manque encore des éléments : des pavés signaux et des séparations de zones, mais aussi des améliorations des TCOs : butoir, sens, grandes courbes, quais, textes, … . Nous allons voir comment réaliser tout cela dans cet article.

Pavés divers

Commençons par quelques pavés utiles, des butoirs et des sens de circulation :

Ces pavés vont nécessiter des formes qui ne seront utilisées que par un pavé, de plus ces formes sont polygonales. Pour éviter d’avoir à créer une classe spécifique pour chaque nouvelle forme, on va écrire une classe FormeSimple pour les formes simples polygonales quelconques :

  1. class FormeSimple extends Forme {
  2. FormeSimple(float... xys) { // constructeur
  3. vertex(xys);
  4. }
  5. }

Le constructeur accepte directement la liste des points du contour.

Pavés sens

Comme exemple d’utilisation de cette nouvelle classe, voici des pavés "sens", un pavé mono-sens et un pavé bi-sens :

  1. class PaveSens extends Pave {
  2. PaveSens() { // constructeur
  3. super(new FormeSimple(0,3, 3.5,3, 3.5,1.5, 5.5,3, 9,3, 9,6, 5.5,6, 3.5,7.5, 3.5,6, 0,6));
  4. }
  5. }
  6.  
  7. class PaveBiSens extends Pave {
  8. PaveBiSens() { // constructeur
  9. super(new FormeSimple(0,3, 1,3, 3,1.5, 3,3, 6,3, 6,1.5, 8,3, 9,3, 9,6, 8,6, 6,7.5, 6,6, 3,6, 3,7.5, 1,6, 0,6));
  10. }
  11. }

Les contours sont un peu compliqués mais il y a beaucoup de points sur ces contours.

Pavés butoirs

Pour les pavés butoirs il faut deux formes, une première forme qui matérialise la traverse du butoir (dessinée en gris-foncé) et une deuxième forme pour la voie (dessinée en gris). Cela donne :

  1. class PaveButoirDroit extends Pave {
  2. PaveButoirDroit() { // constructeur
  3. super(new FormeSimple(9,2, 7,2, 7,7, 9,7),
  4. new FormeSimple(7,3, 0,3, 0,6, 7,6));
  5. }
  6. }
  7.  
  8. class PaveButoirBiais extends Pave {
  9. PaveButoirBiais() { // constructeur
  10. super(new FormeSimple(4,1, 5.75,-0.75, 9.75,3.25, 8,5),
  11. new FormeSimple(-1,8, 5,2, 7,4, 1,10));
  12. }
  13. }

Pavés extensibles

Arc de cercle

Pour faire de jolis TCO des grand arcs de cercles sont bien utiles, on se limitera à des arcs quart de cercle de rayon quelconque, exemples :

Il faut une nouvelle forme (on ne peut pas utiliser la nouvelle classe FormeSimple ici la forme n’étant pas polygonale) :

  1. class FormeArc90 extends Forme {
  2. float nm=0.551784F; // nombre magique
  3.  
  4. FormeArc90(int n) { // constructeur (grand arc de 90° de rayon n)
  5. s.beginShape();
  6. s.vertex(0,3);
  7. s.bezierVertex((9*(n-1)+6)*nm, 3, 9*(n-1)+6, (9*n)-(9*(n-1)+6)*nm, 9*(n-1)+6, 9*(n-1)+9); // cubique
  8. s.vertex(9*(n-1)+3,9*(n-1)+9);
  9. s.bezierVertex(9*(n-1)+3, (9*n)-(9*(n-1)+3)*nm, (9*(n-1)+3)*nm, 6, 0, 6); // cubique
  10. s.endShape();
  11. }
  12. }

Pour avoir de arcs de cercle quasiment parfaits, il faut avoir recours aux courbes de Bézier cubiques ( qui est un cas particulier des courbes de Bézier, ou B-Spline). Les courbes de Bézier cubiques ont deux points de contrôles, en choisissant judicieusement ces deux points de contrôles on obtient des arcs de cercle parfaits, le calcul de la position de ces points fait appel à un « nombre magique » (0.551784).

Il ne reste plus qu’à écrire une classe pavé :

  1. class PaveArc90Grand extends Pave {
  2. PaveArc90Grand(int n) { // constructeur
  3. super(new FormeArc90(n));
  4. taille=n;
  5. }
  6. }

Le rayon du cercle est mémorisé dans la classe Pave dans une variable taille dont la valeur par défaut est un. Cette variable servira par la suite à faciliter le placement des pavés dans la grille du TCO.

Droit

Bien que cela ne soit pas indispensable, de longs pavés droits sont assez pratiques, la forme étant polygonale on n’a pas besoin de forme spécifique :

  1. class PaveDroitLong extends Pave {
  2. PaveDroitLong(int n) { // constructeur
  3. super(new FormeSimple(0,3, 9*n,3, 9*n,6, 0,6));
  4. taille=n;
  5. }
  6. }

Pavés signaux

On a besoin aussi de pavés signaux, par exemple pour les jonctions d’IPCS de l’article précédent :

On a besoin de trois formes, une forme combinée pour le mat et la cible, une forme pour le feu et une forme pour la voie. Pour la voie on a déjà la forme droite, pour le mat et la cible une forme polygonale convient bien, pour le feu c’est plus délicat. On pourrait utiliser les "ronds" de Processing (en fait des ellipses), mais ils ne suivront pas les transformations appliquées au pavé. Il faut donc construire un rond avec des PShape, quatre arcs de cercle obtenus avec des courbes de Bézier quadratiques (un seul point de contrôle) donnent un rond pas très rond, mais comme il est petit cela ne se voit pas. La forme feu :

  1. class FormeFeu extends Forme { // feu pour les signaux
  2. FormeFeu() { //constructeur
  3. s.beginShape(); // quatre arcs de 90°
  4. s.vertex(7.5,-0.5);
  5. s.quadraticVertex(8.5,-0.5, 8.5,0.5);
  6. s.quadraticVertex(8.5,1.5, 7.5,1.5);
  7. s.quadraticVertex(6.4,1.5, 6.5,0.5);
  8. s.quadraticVertex(6.5,-0.5, 7.5,-0.5);
  9. s.endShape();
  10. }
  11. }

Passons au pavé :

  1. class PaveSignal extends Pave {
  2. int feu; // couleur du feu pour le tco
  3.  
  4. PaveSignal(int f) { // constructeur
  5. super(new Forme(3.4,3, 3.4,0.4, 6,0.4, 6,-1, 9,-1, 9,2, 6,2, 6,0.6, 3.6,0.6, 3.6,3),
  6. new FormeFeu(),
  7. new FormeDroit());
  8. feu=f;
  9. }
  10.  
  11. void dessiner() {
  12. formes[0].dessiner(GRIS_FONCE); // cible et mat
  13. formes[1].dessiner(feu); // feu
  14. formes[2].dessiner(couleur); //voie
  15. }
  16.  
  17. Pave manoeuvrer(boolean b) { // pour manoeuvres par clic
  18. switch (feu) {
  19. case ROUGE: feu=VERT; break;
  20. case VERT: feu=ROUGE; break;
  21. case VIOLET: feu=BLANC; break;
  22. case BLANC: feu=VIOLET ; break;
  23. }
  24. return this;
  25. }
  26. }

Le paramètre du constructeur est la couleur du feu que l’on veut voir affichée sur le TCO (rouge, violet, jaune, vert …). Cette couleur est mémorisée dans la variable feu.

La méthode dessiner() doit être redéfinie pour prendre en compte la couleur du feu, les trois formes sont dessinées successivement.

La méthode manoeuvrer() permet de changer la couleur du feu en simulant des ouvertures/fermetures simplifiées avec le même mécanisme que pour les aiguilles (clic de souris sur le pavé).

Retraits

Sur un TCO il faut aussi matérialiser les zones, comme sur les TCOs de la SNCF une petite séparation est faite entre les pavés des zones. Voici ce que cela donne dans nos TCOs :

Cette séparation que nous appellerons "retrait" va être dessinée sur les pavés sous forme d’un petit rectangle de la couleur du fond, en pratique ce rectangle sera formé de deux demi-rectangles (un sur chacun des deux pavés adjacents) pour éviter d’éventuels défauts d’affichage dus à l’ordre d’affichage des pavés.

Pour un pavé il peut y avoir huit retraits possibles, quatre pour les parties droites et quatre pour les angles. Ces huit retraits serons nommés comme sur une rose des vents : nord, sud, est, ouest, nord-est, nord-ouest, sud-est et sud-ouest.

Les petits rectangles à dessiner sont en fait des formes particulières, on a besoin de deux formes, on choisit arbitrairement celles à l’est et au nord-est, on obtiendra les six autres avec des transformations.

Pour regrouper les deux formes retrait on commence par une classe abstraite Retrait, qui hérite de la classe Forme :

  1. abstract class Retrait extends Forme {
  2. final float Rd=0.5,Ra=Rd/1.75; // les tailles des retraits (droit et angle)
  3. }

On peut alors écrire les deux formes retrait dont on a besoin :

  1. class RetraitDroit extends Retrait { // retrait est
  2. RetraitDroit() { // constructeur
  3. vertex(9,3, 9,6, 9-Rd,6, 9-Rd,3);
  4. }
  5. RetraitDroit(int n) { // constructeur
  6. vertex(9*n,3, 9*n,6, 9*n-Rd,6, 9*n-Rd,3);
  7. }
  8. }
  9.  
  10. class RetraitAngle extends Retrait { // retrait nord est
  11. RetraitAngle() { // constructeur
  12. vertex(8,-1, 10,1, 10-Ra,1+Ra, 8-Ra,-1+Ra);
  13. }
  14. }

La forme RetraitDroit a un deuxième constructeur destiné aux formes extensibles (droit et arc90).

Les retraits sont faits sur des pavés, il faut donc modifier cette classe pour les prendre en compte, il faut une structure de données pour mémoriser les retraits et des méthodes pour préciser le retrait, il faut aussi modifier la méthode dessiner() pour dessiner les retraits.

  • Mémorisation des retraits

On ne connait pas à priori le nombre de retraits d’un pavé, Il faut donc utiliser une structure de donnée extensible, ArrayList convient bien. C’est une sorte de tableau dont la taille augmente automatiquement en fonction des besoins. En contrepartie il faut faire l’indiçage avec des méthodes ( add() et get()).

La classe ArrayList est ce que l’on appelle une classe générique, c’est à dire une classe paramétrée par un type. Ici on va l’utiliser pour mémoriser des formes. Voici la déclaration et l’instanciation :

  1. ArrayList<Forme> retraits=new ArrayList<Forme>(); // les retraits

Les types pour la généricité sont écris entre les caractères ’<’ et ’>’ . Ici on a donc un tableau extensible dans lequel on peut mettre des Formes.

  • Méthodes

Pour préciser les retraits on ajoute à la classe Pave, les huit méthodes nécessaires :

  1. Class Pave {
  2. ...
  3. ArrayList<Forme> retraits=new ArrayList<Forme>(); // les retraits
  4. Pave retraitEst() { retraits.add(new RetraitDroit()); return this; }
  5. Pave retraitSud() { retraits.add(new RetraitDroit().rotation()); return this; }
  6. Pave retraitOuest() { retraits.add(new RetraitDroit().rotation(2)); return this; }
  7. Pave retraitNord() { retraits.add(new RetraitDroit().rotation(3)); return this; }
  8.  
  9. Pave retraitNordEst() { retraits.add(new RetraitAngle()); return this; }
  10. Pave retraitSudEst() { retraits.add(new RetraitAngle().rotation()); return this; }
  11. Pave retraitSudOuest() { retraits.add(new RetraitAngle().rotation(2)); return this; }
  12. Pave retraitNordOuest() { retraits.add(new RetraitAngle().rotation(3)); return this; }
  13.  
  14. Pave retraitEst(int n) { retraits.add(new RetraitDroit(n)); return this; }
  15. Pave retraitSud(int n) { retraits.add(new RetraitDroit(n).rotation()); return this; }
  16. Pave retraitOuest(int n) { retraits.add(new RetraitDroit(n).rotation(2)); return this; }
  17. Pave retraitNord(int n) { retraits.add(new RetraitDroit(n).rotation(3)); return this; }
  18. }

Il y a quatre méthodes en plus pour les pavés extensibles. Comme précédemment ces méthodes ont un résultat artificiel pour pouvoir les enchaîner.

  • Dessin

Il ne reste plus qu’a ajouter à la méthode dessiner() le dessin des retraits, cela doit se faire à la fin de la méthode (pour "cacher" les bouts des pavés avec le dessin des retraits) :

  1. for (Forme f : retraits) f.dessiner(GRIS_FOND); // dessin des retraits

C’est ici encore un "forall" (pour toutes les Formes f de retraits …), les retraits sont dessinés avec la couleur du fond.

Placement des paves

Dans la classe TCO il est pratique d’avoir des méthodes qui facilitent le placement des pavés. Le choix ici est fait de remplir le TCO comme on saisit un fichier texte, ligne par ligne et de gauche à droite. Quatre méthodes sont utilisées :

  • une méthode pour ajouter un pavé
  • deux méthodes pour espacer un ou plusieurs pavés
  • une méthode pour passer à la ligne

On a besoin de deux variables pour gérer la ligne et la colonne courante :

  1. int c=0,l=0; // pour la construction
  2.  
  3. void alaligne() { l++; c=0; assert l<LIGNES; } // aller a la ligne
  4.  
  5. void espacer() { c++; assert c<COLONNES; } // espacement
  6. void espacer(int n) { c=c+n; assert c<COLONNES; } // espacement multiple
  7.  
  8. void ajouter(Pave p) { // ajout d'un pave
  9. paves[c][l]=p;
  10. c+=p.taille; assert c<COLONNES; // avancement fonction de la taille du pave
  11. }

Des tests sont faits pour ne pas déborder du TCO ("assert"). D’autres choix de méthodes de placement sont possibles.

Améliorations

Quais

Les quais sont des rectangles dont on peut choisir la largeur et éventuellement la couleur. Une classe PaveQuai est ajoutée avec deux constructeurs un avec juste la largeur du quai et l’autre avec la largeur et la couleur. La méthode dessiner() est redéfinie pour prendre en compte la couleur désirée.

Textes

Des textes sont bien pratiques pour nommer les voies, les provenances et destinations, … Un PaveTexte est ajouté, ce pavé a une grande variété de constructeurs pour pouvoir, en plus du texte, choisir la taille, la couleur et le positionnement. Huit constructeurs sont prévus :

  • un constructeur avec juste le texte
  • un constructeur avec le texte et une taille (réel)
  • un constructeur avec le texte et une couleur (entier)
  • un constructeur avec le texte, une taille et une couleur
  • quatre constructeurs comme les précédents mais avec deux paramètres (réels) en plus permettant d’affiner la position du texte (en hauteur et en largeur)

La méthode dessiner() est redéfinie pour prendre en compte les paramètres. Par défaut le texte est centré au milieu du pavé, mais les deux paramètres optionnels de positionnement permettent de le placer où on veut, ils précisent un décalage en x et un décalage en y (positifs ou négatifs).

Un exemple de textes combinés avec des quais :

Signaux

On ne peut pas encore faire grand chose avec les signaux, mais on peut toutefois faire apparaître une icône du signal réel quand la souris passe sur un pavé signal. Voici quelques exemples de ces icônes :

Toujours avec le TCO d’IPCS cela donne :

Il faut bien sûr préciser le signal (ces signaux seront aussi utilisés par la suite), pour cela on rajoute à la classe PaveSignal un nouveau constructeur de type "signal" et on retouche la méthode manoeuvrer() :

  1. class PaveSignal extends Pave {
  2. Signal signal=null; // le signal
  3. int feu; // couleur du feu pour le tco
  4.  
  5. PaveSignal(int f) { // constructeur
  6. super(new FormeSimple(3.4,3, 3.4,0.4, 6,0.4, 6,-1, 9,-1, 9,2, 6,2, 6,0.6, 3.6,0.6, 3.6,3),
  7. new FormeFeu(),
  8. new FormeDroit());
  9. feu=f;
  10. }
  11.  
  12. PaveSignal(Signal s) { // constructeur
  13. super(new FormeSimple(3.4,3, 3.4,0.4, 6,0.4, 6,-1, 9,-1, 9,2, 6,2, 6,0.6, 3.6,0.6, 3.6,3),
  14. new FormeFeu(),
  15. new FormeDroit());
  16. signal=s; feu=s.feu.couleur;
  17. }
  18.  
  19. void dessiner() {
  20. formes[0].dessiner(GRIS_FONCE); // cible et mat
  21. formes[1].dessiner(feu); // feu
  22. formes[2].dessiner(couleur); //voie
  23. for (Forme f : retraits) f.dessiner(GRIS_FOND); // dessin des retraits
  24. }
  25.  
  26. Pave manoeuvrer(boolean b) { // pour manoeuvres par clic
  27. if (signal!=null) {
  28. if (signal.ferme()) { if (b) signal.ouvrirManoeuvre(); else signal.ouvrir(); } else signal.fermer();
  29. couleur=signal.feu.couleur;
  30. } else {
  31. switch (feu) {
  32. case ROUGE: feu=VERT; break; // avertissements ??? (vl)
  33. case VERT: feu=ROUGE; break;
  34. case VIOLET: feu=BLANC; break;
  35. case BLANC: feu=VIOLET ; break;
  36. }
  37. }
  38. return this;
  39. }
  40. ...
  41. }

Le deuxième constructeur mémorise le signal, et extrait de ce signal la couleur à mettre sur le TCO. La méthode manoeuvrer() est modifiée pour prendre en compte le signal et pour pouvoir le manœuvrer, un clic gauche l’ouvre en mode "ligne", un clic droit en mode "manoeuvre".

Pour les signaux on va reprendre ceux de l’article Un gestionnaire en C++ pour votre réseau (2). Dans cet article les classes pour les signaux sont écrites en C++, on va ici les traduire en Java, voir l’article Processing pour nos trains pour les passages d’un langage à l’autre. Mais toutes les explications sur l’écriture des classes restent les mêmes.

Comme nous n’avons pas encore les moyens d’accéder aux signaux précédents et suivants (mais cela viendra !), on va se contenter ici d"une version "édulcorée" des signaux.

Pour l’instant on ne peut pas faire grand chose avec les signaux (mais cela viendra), mais on peut tout de même, comme on en a parlé précédemment, dessiner le signal réel quand la souris passe sur le pavé signal.

Dans l’article précédent il y avait déjà un gestionnaire d’événements pour les clics de souris :

  1. void mouseClicked() { int l,c; ; Pave p;
  2. l=(mouseY-BORDURE)/TAILLE_CASE/(int)ZOOM; // calcul de la ligne
  3. c=(mouseX-BORDURE)/TAILLE_CASE/(int)ZOOM; // calcul de la colonne
  4. if (l<0 || l>=LIGNES || c<0 || c>=COLONNES) return; // pas dans tco
  5. p=tco.paves[c][l]; // obtension du pave
  6. if (p!=null) p.manoeuvrer(mouseButton==RIGHT); // manoeuvre des aiguilles
  7. }

Sur le même modèle on écrit un gestionnaire des mouvement de la souris :

  1. PaveSignal paveSignalSelectionne=null;
  2.  
  3. void mouseMoved() { int l,c; ; Pave p;
  4. l=(mouseY-BORDURE)/TAILLE_CASE/(int)ZOOM; // calcul de la ligne
  5. c=(mouseX-BORDURE)/TAILLE_CASE/(int)ZOOM; // calcul de la colonne
  6. if (l<0 || l>=LIGNES || c<0 || c>=COLONNES) return; // pas dans tco
  7. p=tco.paves[c][l]; // obtension du pave
  8. if (p==null || !(p instanceof PaveSignal)) { paveSignalSelectionne=null; return; }
  9. paveSignalSelectionne=(PaveSignal)p;
  10. }

La variable globale paveSignalSelectionne mémorise le pavé sélectionné (sinon null). L’opérateur instanceof permet de tester la classe réelle d’un objet, ici un PaveSignal

Reste à dessiner le signal quand il faut, cela se fait dans le TCO tout à la fin de la méthode dessiner() pour que le signal soit dessiné au dessus de tout.

  1. void dessiner() {
  2. if (paveSignalSelectionne!=null) { // dessin de la cible du signal
  3. for (l=0; l<LIGNES; l++) for (c=0; c<COLONNES; c++) { // dessin des paves
  4. p=paves[c][l]; // un des paves
  5. if (p!=null && p==paveSignalSelectionne) {
  6. translate(c*TAILLE_CASE,l*TAILLE_CASE);
  7. dessinSignal();
  8. }
  9. }
  10. }
  11. }

La méthode dessinSignal() est assez compliquée, on ne fera ici que décrire son fonctionnement, pour plus d’information voir les fichiers accompagnant l’article, cette méthode comporte plusieurs étapes :

  • réglage du zoom
  • obtention du signal
  • obtention de l’image du signal en utilisant la méthode icone() de la classe signal
  • recherche du centre du mat du signal pour le positionner au centre du pavé
  • dessin de l’image

La méthode icone() charge la bonne image, un mécanisme de cache est mis en oeuvre pour accélérer les chargements. La méthode permet aussi d’avoir un "halo" autour de l’image, pour qu’elle ressorte bien au dessus des composants du TCO, quand son paramètre est "vrai".

Le halo est fait de la manière suivante, un pixel de la couleur du fond est ajouté tout autour de l’image en suivant son contour, cette opération est répétée seize fois avec un pixel de plus en plus transparent. Plusieurs méthodes utilitaires sont nécessaires.

Fichiers

Quelques précisions sur les fichiers accompagnant l’article :

Fichiers à télécharger

Le dossier "Exemple_2_0" contient le programme Processing conforme aux descriptions de l’article.

Améliorations

Le dossier "Exemple_2_1" contient une version améliorée du précédent. Cette "amélioration" se fait essentiellement avec la prise en compte des signaux réels. Deux dossiers contiennent une grande variété d’icônes de signaux lumineux et de signaux mécaniques.

Aide

Comme pour l’article précédent, une petite application "Aide2" facilite l’écriture des TCOs, notamment pour les signaux.

Cette application propose trois palettes flottantes :

  • une palette avec les pavés de base enrichis des butoirs et des sens
  • une palette avec les pavés extensibles droit et arc90, ajustables avec la molette de la souris
  • une palette avec les signaux, trois choix de signaux sont sélectionnables avec les trois boutons ("lum", "bal" et "mec") signaux lumineux, signaux de BAL et signaux mécaniques.

Avec cette application Processing est poussé dans ses derniers retranchements, et "bogue" de temps en temps dans la gestion de mémoire, relancer dans ce cas.

Le mode d’emploi est le même que celui de l’aide du précédent article. Pour changer la taille des pavés extensibles utiliser la molette de la souris.

Bilan

On a maintenant à peu près tout ce qu’il faut pour dessiner des TCOs, on peut rajouter assez facilement des éléments manquants, par exemple des demi pavés :

L’utilisation principale des demi-pavés est de pouvoir faire des séparations de zones (retraits) au milieu d’un pavé droit ou biais. En pratique cela implique généralement de mettre deux demi-pavés dans une même case du TCO, il faut alors une structure de données adaptée pour mémoriser les pavés.

Exemple des jonctions croisées :

Ces jonctions posent un problème pour le cœur du croisement car les pavés se chevauchent, pour que cela soit joli il faut sur-dessiner le cœur de croisement en fonction de la position des aiguilles (noter que les quatre appareils de voie encadrant le croisement peuvent êtres quelconques : aiguilles simples, aiguilles doubles voire croisements).

Autre exemple une plaque tournante :

Bien évidemment elle peut être animée.

Concernant la géométrie des pavés (largeur, hauteur, épaisseur de la voie, …), il est facile d’en changer, voici quelques exemples :

La largeur est deux fois celle de la hauteur, les pavés font 18x9 points.

Là on joue sur l’épaisseur de la voie, les pavés font 10x10 points.

Sur les pavés de base (ceux de l’article précédent) il n’y a que cinq modifications à faire, revoir les contours des pavés de base (droit, biais et Arc45) et revoir les transformations des formes (symétrie et rotation), c’est pratiquement tout. Sur les autres pavés cela demande un peu plus de travail.

Il y a quelques précautions à prendre, il faut que les bouts des pavés se raccordent parfaitement aux autres, il importe aussi que l’épaisseur des biais soit le plus possible égale celle des droits.

Dans l’article précédent on a fait des choix pour la géométrie des pavés avec une taille de pavés 9x9 points, ces choix sont motivés par deux choses, premièrement avoir des droits et des biais d’épaisseur presque identique (ici 3 et 2.828), deuxièmement avoir des voies suffisamment épaisses pour pouvoir écrire des informations dedans, par exemple des noms de trains, mais aussi pour avoir assez d’épaisseur pour pouvoir faire circuler des trains virtuels, on en parlera par la suite.

On pourrait paramétrer les programmes pour prendre en compte les variantes dans la géométrie des pavés, mais cela rendrait le programme totalement illisible au niveau des formes.

Dans de prochains articles on va faire des traitements sur l’ensemble des pavés pour fabriquer automatiquement tout ce qui est nécéssaire au fonctionnement des zones. On s’intéressera aussi à l’interface entre le TCO et un gestionnaire de réseau sur Arduino.

1 Message

Réagissez à « TCOs en Processing (2) »

Qui êtes-vous ?
Votre message

Pour créer des paragraphes, laissez simplement des lignes vides.

Lien hypertexte

(Si votre message se réfère à un article publié sur le Web, ou à une page fournissant plus d’informations, vous pouvez indiquer ci-après le titre de la page et son adresse.)

Rubrique « Programmation »

Comment gérer le temps dans un programme ?

La programmation, qu’est ce que c’est

Types, constantes et variables

Installation de l’IDE Arduino

Répéter des instructions : les boucles

Les interruptions (1)

Instructions conditionnelles : le if … else

Instructions conditionnelles : le switch … case

Comment concevoir rationnellement votre système

Comment gérer l’aléatoire ?

Calculer avec l’Arduino (1)

Calculer avec l’Arduino (2)

Les structures

Systèmes de numération

Les fonctions

Trois façons de déclarer des constantes

Transcription d’un programme simple en programmation objet

Ces tableaux qui peuvent nous simplifier le développement Arduino

Les chaînes de caractères

Trucs, astuces et choses à ne pas faire !

Processing pour nos trains

Arduino : toute première fois !

Démarrer en Processing (1)

Comment réussir son projet Arduino

Le monde des objets (1)

Le monde des objets (2)

Le monde des objets (3)

Le monde des objets (4)

Les pointeurs (1)

Les pointeurs (2)

Les Timers (I)

Les Timers (II)

Les Timers (III)

Les Timers (IV)

Les Timers (V)

Bien utiliser l’IDE d’Arduino (1)

Bien utiliser l’IDE d’Arduino (2)

Piloter son Arduino avec son navigateur web et Node.js (1)

Piloter son Arduino avec son navigateur web et Node.js (2)

Piloter son Arduino avec son navigateur web et Node.js (3)

Piloter son Arduino avec son navigateur web et Node.js (4)

Les derniers articles

TCOs en Processing (2)


Pierre59

Comment concevoir rationnellement votre système


Jean-Luc

Comment réussir son projet Arduino


Christian

Piloter son Arduino avec son navigateur web et Node.js (4)


bobyAndCo

TCOs en Processing


Pierre59

Ces tableaux qui peuvent nous simplifier le développement Arduino


bobyAndCo

Processing pour nos trains


Pierre59

Piloter son Arduino avec son navigateur web et Node.js (3)


bobyAndCo

Piloter son Arduino avec son navigateur web et Node.js (2)


bobyAndCo

Démarrer en Processing (1)


DDEFF

Les articles les plus lus

Les interruptions (1)

Les Timers (I)

Ces tableaux qui peuvent nous simplifier le développement Arduino

Répéter des instructions : les boucles

Comment gérer le temps dans un programme ?

Les Timers (II)

Bien utiliser l’IDE d’Arduino (1)

Calculer avec l’Arduino (1)

Piloter son Arduino avec son navigateur web et Node.js (1)

Les fonctions