L'ordinateur

Dessins automatiques de tuyaux de façade.

L'Hydraule


La compréhension des points $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8 et $x9 ainsi que les points $y1, $y2, $y3, $y4 et $y5 se fait en consultant le document relatif au traçage de l'accolade renaissance. Ce document a été écrit en cours de programmation et doit être considéré comme faisant partie de la publication du code source de cet utilitaire sous licence GPL.

Le code.

facade.php.

<?php
/*
                                                ----------------------------------------------------
                                                                        _
                 ORGANUM                                               | | _
                                                       Sébastien       | || | _
              Logiciel libre                           Matthieu        | || || | _
          de gestion de données                        Cosson          | || || || | _
           de facture d'orgues                         Jacquet         | || || || || | _
                                                                       | || || || || || | _
                                                                       | || || || || || || |
                    M                                                  | || || || || || || |
                  *   *                                ,-~~-.___.      | || || || || || || |___
                S A T O R                             /  | .     \     |_||_||_||_||_||_||_|  /|
              * A R E P O *                          (   )        O    |_||_||_||_||_||_||_| / |
            S   T E N E T   C                         \_/-. ,----'    / V  V  V  V  V  V  V /  |
              * O P E R A *                               ====      _/____________________ /  /
                R O T A S                                /  \-'~;  /|  The Organbuilder   |  /
                  *   *                                 /  __/~|  /_|   and his organ     | /
                    J                                o=(_______|  |_|_____________________|/

                                                ----------------------------------------------------
                                                   Site web : http://www.hydraule.org/
                                                     E-mail : smcj@hydraule.org
                                                ----------------------------------------------------

*/

// Couleurs du dégradé des tuyaux.
$coulStart = "#ffffff"; $coulPresqueEnd = "#606060"; $coulEnd = "#000000";

function traceMontant($posX, $posY, $coloriage = 1, $largeur, $longueur)
{
 $remplissage = $coloriage == 1 ? "#885522" : "none";
 echo("  <rect width=\"$largeur\" height=\"$longueur\" x=\"" . ($posX - ($largeur / 2)) . "\" y=\"" . ($posY - $longueur) . "\" style=\"fill:$remplissage;\" />\n\n" );
};

function traceTuyau($noOrdre = 0, $posX = 600, $posY = 800, $coloriage = 1, $diamCorps = 0, $longCorps = 500, $longPied = 0, $largBouch = 0, $hautBouch = 0, $hautLevSup = 0, $hautLevInf = 0, $tls = 1, $tli = 1)
{
 if ( $diamCorps == 0) { $diamCorps = $longCorps / 20; };                             // Vingtième de la longueur du corps.
 if ( $largBouch == 0) { $largBouch = ($diamCorps * pi()) / 4;};                      // Quart de la circonférence du diamètre.
 if ( $hautBouch == 0) { $hautBouch = $largBouch / 5; };                              // Cinquième de la largeur de la bouche.
 if ($hautLevSup == 0) {$hautLevSup = $largBouch * 1.5; };                            // Une fois et demie la hauteur de la bouche.
 if ($hautLevInf == 0) {$hautLevInf = $largBouch / 1.7; };                            // 1,7 fois moins de la largeur de la bouche.
 if (  $longPied == 0) { ($longPied = $hautLevSup + $hautLevInf + $hautBouch) * 2; }; // Septième de la longueur du corps.

 echo("  <g id=\"tuyau_$noOrdre\">\n");

 // Traçage du pied.
 $basePied = $diamCorps / 7; // Septième du diamètre du corps comme diamètre de pied.
 $x1= $posX - ( $basePied / 2) ; $y1 = $posY; $x2= $posX - ($diamCorps / 2) ; $y2 = ($posY - $longPied);
 $x3= $posX + ($diamCorps / 2) ; $y3 = $y2;   $x4= $posX + ( $basePied / 2) ; $y4 = $posY;
 $remplissage = $coloriage == 1 ? "url(#pied)" : "none";
 echo("   <path d=\"M $x1 $y1 L $x2 $y2 L $x3 $y3 L $x4 $y4 Z\" style=\"fill:$remplissage;\" filter=\"url(#ombreCorps)\" />\n");

 // Traçage du corps.
 $remplissage = $coloriage == 1 ? "url(#corps)" : "none";
 echo("   <rect width=\"$diamCorps\" height=\"$longCorps\" x=\"$x2\" y=\"" . ($posY - $longPied - $longCorps) . "\" style=\"fill:$remplissage;\" filter=\"url(#ombreCorps)\" />\n" );

 // Détermination des points de traçage de la galoche et de la bouche.
 $soudureY = ($posY - $longPied);
 $x1 = $posX - ($largBouch / 2); $x2 = $posX - (($largBouch / 8) * 3); $x3 = $posX - ($largBouch / 4); $x4 = $posX - ($largBouch / 8);
 $x5 = $posX;
 $x6 = $posX + ($largBouch / 8); $x7 = $posX + ($largBouch / 4); $x8 = $posX + (($largBouch / 8) * 3); $x9 = $posX + ($largBouch / 2);

 $y1 = ($soudureY - $hautBouch - $hautLevSup); $y5 = ($soudureY - $hautBouch - $hautLevSup + ($largBouch / 2));
 $y2 = $y1 + (($y5 - $y1) / 4); $y3 = $y1 + (($y5 - $y1) / 2); $y4 = $y5 - (($y5 - $y1) / 4);

 // Traçage de la bouche.
 echo("   <rect width=\"$largBouch\" height=\"$hautBouch\" x=\"$x1\" y=\"" . ($posY - $longPied - $hautBouch) . "\" style=\"fill:black;\" />\n" );

 // Traçage de la lèvre supérieure .
 $remplissage = $coloriage == 1 ? "url(#levreSup)" : "none";
 switch ($tls)
 {
  Case 0: // Applatissage.
   echo("   <rect width=\"$largBouch\" height=\"$hautLevSup\" x=\"$x1\" y=\"$y1\" style=\"fill:$remplissage;\" />\n" );
  break;
  Case 1: // Roman.
   echo("   <path d=\"M $x1 $y5 A 7 7 0 0 1 $x9 $y5 L $x9 " . ($soudureY - $hautBouch). " L $x1 " . ($soudureY - $hautBouch) . "Z\" style=\"fill:$remplissage;\" />\n");
  break;
  Case 2: // Gothique.
   echo("   <path d=\"M $x1 " . ($soudureY - $hautBouch) . " Q $x1 $y5 $posX " . ($soudureY - $hautBouch  - $hautLevSup) . " Q $x9 $y5 $x9 " . ($soudureY - $hautBouch) . "Z\" style=\"fill:$remplissage;\" />\n");
  break;
  Case 3: // Renaissance.
   echo("   <path d=\"M $x1 $y5 C $x1 $y4 $x2 $y3 $x3 $y3 C $x4 $y3 $x5 $y2 $x5 $y1 C $x5 $y2 $x6 $y3 $x7 $y3 C $x8 $y3 $x9 $y4 $x9 $y5 L $x9 " . ($soudureY - $hautBouch). " L $x1 " . ($soudureY - $hautBouch) . "Z\" style=\"fill:$remplissage;\" />\n");
  break;
  Case 4: // Triangle.
   echo("   <path d=\"M $x1 " . ($soudureY - $hautBouch) . " L $posX " . ($soudureY - $hautBouch - $hautLevSup) . " L $x9 " . ($soudureY - $hautBouch) . "Z\" style=\"fill:$remplissage;\" />\n");
  break;
 };

 // Traçage de la lèvre inférieure -->
 // Redétermination des points de traçage Y pour permettre de mettre la pointe de l'accolade en bas.
 $y1 = ($soudureY + $hautLevInf - ($largBouch / 2)); $y5 = ($soudureY + $hautLevInf);
 $y2 = $y1 + (($y5 - $y1) / 4); $y3 = $y1 + (($y5 - $y1) / 2); $y4 = $y5 - (($y5 - $y1) / 4);

 $remplissage = $coloriage == 1 ? "url(#levreInf)" : "none";
 switch ($tli)
 {
  Case 0: // Applatissage.
   echo("   <rect width=\"$largBouch\" height=\"$hautLevInf\" x=\"$x1\" y=\"$soudureY\" style=\"fill:$remplissage;\" />\n" );
  break;
  Case 1: // Roman.
   echo("   <path d=\"M $x1 $y1 A 7 7 0 0 0 $x9 $y1 L $x9 $soudureY L $x1 $soudureY Z\" style=\"fill:$remplissage;\" filter=\"url(#ombreLevreInf)\" />\n");
  break;
  Case 2: // Gothique.
   echo("   <path d=\"M $x1 $soudureY Q $x1 " . ($y1 + ($hautLevInf / 2.5)) . " $posX "  . ($soudureY + $hautLevInf) . " Q $x9 " . ($y1 + ($hautLevInf / 2.5)) . " $x9 $soudureY Z\" style=\"fill:$remplissage;\" />\n");
  break;
  Case 3: // Renaissance.
   echo("   <path d=\"M $x1 $y1 C $x1 $y2 $x2 $y3 $x3 $y3 C $x4 $y3 $x5 $y4 $x5 $y5 C $x5 $y4 $x6 $y3 $x7 $y3 C $x8 $y3 $x9 $y2 $x9 $y1 L $x9 $soudureY L $x1 $soudureY Z\" style=\"fill:$remplissage;\" filter=\"url(#ombreLevreInf)\" />\n");
  break;
  Case 4: // Triangle.
   echo("   <path d=\"M $x1 $soudureY L $posX " . ($soudureY + $hautLevInf) . " L $x9 $soudureY Z\" style=\"fill:$remplissage;\" />\n");
  break;
 };

 echo ("  </g>\n\n");
};

header("Content-Type:image/svg+xml");
echo('<?xml version="1.0" encoding="UTF-8"?>' . "\n");
echo('<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/PR-SVG-20010719/DTD/svg10.dtd">' . "\n");

?>
<svg  xmlns="http://www.w3.org/2000/svg" version="1.1" width="1200" height="800">
 <title>Disposition de tuyaux d'orgue en façade.</title>
 <desc>Essai d'application graphiques de données de facture d'orgues.</desc>

 <!-- Définition des dégradés -->
 <defs>
  <linearGradient id="corps" x1="0" y1="0" x2="1" y2="0">
   <stop offset="0.01" style="stop-color:<?php echo($coulPresqueEnd); ?>;" />
   <stop offset="0.2"  style="stop-color:<?php echo($coulStart);      ?>;" />
   <stop offset="1"    style="stop-color:<?php echo($coulPresqueEnd); ?>;" />
  </linearGradient>
  <linearGradient id="pied" x1="0" y1="0" x2="1" y2="0.3">
   <stop offset="0.01" style="stop-color:<?php echo($coulPresqueEnd); ?>;" />
   <stop offset="0.2"  style="stop-color:<?php echo($coulStart);      ?>;" />
   <stop offset="0.9"  style="stop-color:<?php echo($coulPresqueEnd); ?>;" />
   <stop offset="1"    style="stop-color:<?php echo($coulEnd);        ?>;" />
  </linearGradient>
  <linearGradient id="levreSup" x1="0" y1="1" x2="0" y2="0">
   <stop offset="0.1" style="stop-color:<?php echo($coulStart);      ?>;" />
   <stop offset="0.9"  style="stop-color:<?php echo($coulPresqueEnd); ?>;" />
   <stop offset="1"    style="stop-color:<?php echo($coulEnd);        ?>;" />
  </linearGradient>
  <linearGradient id="levreInf" x1="0" y1="0" x2="0" y2="1">
   <stop offset="0.01" style="stop-color:<?php echo($coulStart);      ?>;" />
   <stop offset="0.8"  style="stop-color:<?php echo($coulPresqueEnd); ?>;" />
   <stop offset="1"    style="stop-color:<?php echo($coulEnd);        ?>;" />
  </linearGradient>
 </defs>

 <!-- Définition de l'ombre portée des corps et des lèvres inférieures -->
 <filter id="ombreCorps">
  <feGaussianBlur in="SourceAlpha" stdDeviation="1" result="flou" />
  <feOffset in="flou" dx="1" dy="0" result="flouDécalé" />
  <feMerge>
   <feMergeNode in="flouDécalé" />
   <feMergeNode in="SourceGraphic" />
  </feMerge>
 </filter>
 <filter id="ombreLevreInf">
  <feGaussianBlur in="SourceAlpha" stdDeviation="1" result="flou" />
  <feOffset in="flou" dx="1" dy="1" result="flouDécalé" />
  <feMerge>
   <feMergeNode in="flouDécalé" />
   <feMergeNode in="SourceGraphic" />
  </feMerge>
 </filter>

<?php
 // Lecture du fichier CSV.
 $adresseFichier = isset($_GET ['url']) ? $_GET ['url'] : "";                   // L'adresse du fichier est dans l'URL.
                                                                                // Le fichier est transféré depuis le disque dur.
 if (!$adresseFichier) {$adresseFichier = isset($_FILES['CSVfichier']['tmp_name']) ? $_FILES['CSVfichier']['tmp_name'] : ""; };

 if ((is_uploaded_file($adresseFichier)) || ($adresseFichier))
 {
  // Lecture de la première ligne pour la détermination du séparateur (merci Merdo$oft) en fonction de la première occurrence apparue.
  $fichierCSV = fopen($adresseFichier, "r");                                    // Ouverture du fichier.
  $texte = fgets($fichierCSV); $ligne = 1;                                      // Lecture de la première ligne qui contient les titres de colonnes.
  // On est prié de ne pas mettre de virgule ou de point-virgule dans le contenu des cellules de titre.
  if (strpos($texte, ";")) {$separateur = ";";} else {$separateur = ","; };

  while ($donnees = fgetcsv($fichierCSV, 500, $separateur))
  {
   // Il est entendu que les valeurs définies par défaut ici le sont aussi dans la fonction traceTuyau(), mais la lecture CSV n'est ici qu'un exemple et ne doit pas être considérée comme une finalité.
         $note_D[$ligne] = isset($donnees[0] ) ? $donnees[0]  : "";             // Nom de la note (pas utilisé pour l'instant).
          $jeu_D[$ligne] = isset($donnees[1] ) ? $donnees[1]  : "";             // Nom du jeu (pas utilisé pour l'instant).
        $ordre_D[$ligne] = isset($donnees[2] ) ? $donnees[2]  : 0;              // Numéro d'ordre des tuyaux et des groupes (ordre négatif) ; si < 1, c'est un montant ; si = 0 : spécifie que c’est la fin de la façade.
         $posY_D[$ligne] = isset($donnees[3] ) ? $donnees[3]  : 0;              // Position Y DE LA BASE du tuyau (ou du montant).
    $coloriage_D[$ligne] = isset($donnees[4] ) ? $donnees[4]  : 0;              // Coloriage ou non du tuyau (ou du montant).
    $diamCorps_D[$ligne] = isset($donnees[5] ) ? $donnees[5]  : 0;              // Diamètre du corps (ou largeur du montant).
    $longCorps_D[$ligne] = isset($donnees[6] ) ? $donnees[6]  : 0;              // Longueur du corps (ou du montant).
     $longPied_D[$ligne] = isset($donnees[7] ) ? $donnees[7]  : 0;              // Hauteur du pied ou numéro du groupe.
    $largBouch_D[$ligne] = isset($donnees[8] ) ? $donnees[8]  : 0;              // Largeur de bouche ou du groupe (entre montants).
    $hautBouch_D[$ligne] = isset($donnees[9] ) ? $donnees[9]  : 0;              // Hauteur de bouche.
   $hautLevSup_D[$ligne] = isset($donnees[10]) ? $donnees[10] : 0;              // Hauteur de lèvre supérieure.
   $hautLevInf_D[$ligne] = isset($donnees[11]) ? $donnees[11] : 0;              // Hauteur de lèvre inférieure.
          $tls_D[$ligne] = isset($donnees[12]) ? $donnees[12] : 1;              // Type de dessin de la lèvre supérieure. 0 = Plat - 1 = Roman - 2 = Gothique - 3 = Renaissance - 4 = Triangle.
                                                                                // ou nombre de tuyaux du groupe.
          $tli_D[$ligne] = isset($donnees[13]) ? $donnees[13] : 1;              // Type de dessin de la lèvre inférieure. 0 = Plat - 1 = Roman - 2 = Gothique - 3 = Renaissance - 4 = Triangle.
	                                                                        // ou nature du groupe. 1 = plate-face - 2 = tourelle circulaire - 3 = tiers point.
   $ligne++;
  };
  fclose($fichierCSV);
 };

 // Trace les tuyaux et les montants en fonction des données lues dans le fichier CSV.
 $ech = 4.5; $positionX = 10; $compteTuyaux = 0;
 echo(" <g id=\"facade\" style=\"stroke:black; stroke-width:0.4;\">\n");

 for ($i = 2; $i <= ($ligne - 1); $i++)
 {
       $ordre_D[0] =      $ordre_D[$i];
        $posY_D[0] =       $posY_D[$i] / $ech;
   $coloriage_D[0] =  $coloriage_D[$i];
   $diamCorps_D[0] =  $diamCorps_D[$i] / $ech;
   $longCorps_D[0] =  $longCorps_D[$i] / $ech;
    $longPied_D[0] =   $longPied_D[$i] / $ech;
   $largBouch_D[0] =  $largBouch_D[$i] / $ech;
   $hautBouch_D[0] =  $hautBouch_D[$i] / $ech;
  $hautLevSup_D[0] = $hautLevSup_D[$i] / $ech;
  $hautLevInf_D[0] = $hautLevInf_D[$i] / $ech;
         $tls_D[0] =        $tls_D[$i];
         $tli_D[0] =        $tli_D[$i];

  if ($ordre_D[0] >= 1)                                                               // C'est un tuyau.
  {
   $compteTuyaux ++;
   $positionX += ($ecartTuyau + ($diamCorps_D[0] / 2));                               // Un écart et un demi tuyau.
   traceTuyau($ordre_D[0], $positionX, (700 + $posY_D[0]), $coloriage_D[0], $diamCorps_D[0], $longCorps_D[0], $longPied_D[0], $largBouch_D[0], $hautBouch_D[0], $hautLevSup_D[0], $hautLevInf_D[0], $tls_D[0], $tli_D[0]);
   $positionX += ($diamCorps_D[0] / 2);                                               // Rajoute juste un demi tuyau.
   if ($compteTuyaux == $nbTtotalTuyaux) {$positionX += $ecartTuyau; };               // Sauf en fin de groupe rajoute un écart.
  }
  else                                                                                // C'est un montant.
  {
   echo("  <!-- Montant_" . $ordre_D[0] . " -->\n");
   if ($ordre_D[0] != 0)                                                              // Si on est pas en fin de façade,
   {                                                                                  // spécification des valeurs du prochain groupe.
    $sommeLargTuyaux = 0;                                                             // Fait la somme de la largeur des tuyaux de la plate-face.
    for ($j = ($i + 1); $j <= ($i + $tls_D[0]); $j++) {$sommeLargTuyaux += $diamCorps_D[$j]; };
    $ecartTuyau = (($largBouch_D[0] - ($sommeLargTuyaux  / $ech)) / ($tls_D[0] + 1)); // Calcule l'écart entre les tuyaux de la plate-face.
    $nbTtotalTuyaux = $tls_D[0];                                                      // Prend note du nombre total de tuyaux du groupe.
   };

   $positionX += ($diamCorps_D[0] / 2);                                               // Un demi-montant.
   traceMontant($positionX, (700 + $posY_D[0]), $coloriage_D[0], $diamCorps_D[0], $longCorps_D[0]);
   $positionX += ($diamCorps_D[0] / 2);                                               // Un demi-montant.
   $compteTuyaux = 0;                                                                 // Met le compteur de tuyaux à zéro.
  };
 };
 echo (" </g>\n");

?>
</svg>