Darkoneko's Weblog

Yesterday, today, and no future / time waits for no one

[html5] carte 2 – carte hexagonale

Posted by DarkoNeko sur samedi 29 juin 2013

Ce billet fait parti de la série « bidouillons avec HTML5« .

Suite à mon précédent article, je passe maintenant aux cases hexagonales.
La base HTML reste la même :

<!DOCTYPE html5>
<html>
<body>
<canvas id ="canvas1" width="400" height="300" style="border:5px solid black;">
</canvas>
</body>
</html>

Dessine moi un hexagone

Mathématiquement

hexagoneBon pour commencer, ça se dessine comment exactement, un hexagone ?
N’oubliez pas que sur un canvas, l’origine [0;0] est en haut à gauche. L’axe vertical est inversé, donc « y » est à son minimum au point d’origine.

Trait par trait (d’une longueur A), d’en haut à gauche et dans le sens des aiguilles d’une montre, ça donne ça :

  • Position de départ : [x, y]
  • Trait horizontal du haut : [+A, +0]
  • diagonale côté haut droit : [+A*sin(30°), +A*cos(30°)]
  • diagonale côté bas droit : [-A*sin(30°), +A*cos(30°)]
  • Trait horizontal du bas : [-A, -0]
  • diagonale côté bas gauche : [-A*sin(30°), -A*cos(30°)]
  • diagonale côté haut gauche : [+A*sin(30°), -A*cos(30°)]

Et niveau code ?

Notez que contrairement à la liste (ou la position est indiquée incrémentalement, par rapport à celle de la fin du trait précédent), le code ci dessous garde tout du long la position de départ comme référentiel :

<script language="javascript" type="text/javascript">
var c1=document.getElementById("canvas1");
var pinceau =c1.getContext("2d");

initial_h = 100; //position verticale de base
initial_w = 100; //position horizontale de base

unit = 50; //longueur d'un coté de l'hexagone
//pour ne pas avoir à le recalculer à chaque fois
sin_unit = unit * Math.sin(30*Math.PI/180); 
cos_unit = unit * Math.cos(30*Math.PI/180);

pinceau.moveTo(initial_w                  , initial_h); //point de départ
pinceau.lineTo(initial_w + unit           , initial_h);
pinceau.lineTo(initial_w + unit + sin_unit, initial_h + cos_unit);
pinceau.lineTo(initial_w + unit           , initial_h + 2 * cos_unit);
pinceau.lineTo(initial_w                  , initial_h + 2 * cos_unit);
pinceau.lineTo(initial_w - sin_unit       , initial_h + cos_unit);
pinceau.lineTo(initial_w                  , initial_h); //retour au point de départ
pinceau.stroke();
</script>

canvas2-1

Comme sur des roulettes ! Passons au remplissage

Tracer la carte

Tracer chaque hexagone de la carte étant fastidieux et inefficace, j’ai décidé de tracer les diagonales par colonnes, puis d’ajouter les traits horizontaux manquants.

Code

<script language="javascript" type="text/javascript">
var c1=document.getElementById("canvas1");
var pinceau=c1.getContext("2d");

var unit = 40;
var sin_unit = unit * Math.sin(30*Math.PI/180);
var cos_unit = unit * Math.cos(30*Math.PI/180);

//trace the diagonals
var count = 0;

for(var w = 0 ; w < c1.width ; w += unit + sin_unit) {
   if( count % 2 == 0) {
      pinceau.moveTo(w , 0); //point de depart
      for(var h = 0 ; h < c1.height ; h += 2 * cos_unit) {
         pinceau.lineTo(w + sin_unit , h + cos_unit); /* \ */
         pinceau.lineTo(w, h + 2 * cos_unit);        /* / */
      }
   } else {
      pinceau.moveTo(w + sin_unit, 0); //point de depart
      for(var h = 0 ; h < c1.height ; h += 2 * cos_unit) {
         pinceau.lineTo(w, h + cos_unit);               /* / */
         pinceau.lineTo(w + sin_unit, h + 2 * cos_unit); /* \ */
      }
   }
   count++;
}

//trace the lines
count = 0;

for(var w = 0 ; w < c1.width ; w += unit + sin_unit) {
   if( count % 2 == 0) {
      for(var h = 0 ; h < c1.height ; h += 2 * cos_unit) {
         pinceau.moveTo(w + sin_unit, h + cos_unit);
         pinceau.lineTo(w + sin_unit + unit , h + cos_unit);
      }
   } else {
      for(var h = cos_unit ; h < c1.height ; h += 2 * cos_unit) {
         pinceau.moveTo(w + sin_unit, h + cos_unit); 
         pinceau.lineTo(w + sin_unit + unit, h + cos_unit);
      }
   }
   count++;
}
pinceau.stroke();
</script>

Visuellement

Étape 1 :
canvas2-3b
Étape 2 :
canvas2-4

Sorry, the comment form is closed at this time.