Ce billet fait parti de la série "bidouillons avec HTML5".
Mon précédent article a vu la création d’une carte à cases hexagonales. Aujourd’hui vous allons voir, en pratique, comment ajouter quelquechose dans cette carte.
Système de coordonnées ?
En programmation, les données d’une carte sont typiquement stockées dans un tableau à deux dimensions, chaque case du tableau correspondant à une case de la carte. Ça fonctionne très bien avec des cases carrées, mais comment faire avec une carte hexagonale ? (mes coupains twittos se souviendrons de mon raclage de cerveau sur le sujet)
À ma grande surprise, cela reste similaire. C’est toujours un système de coordonnées cartésiennes, sauf qu’il n’est pas orthonormé : au lieu d’avoir un axe horizontal, l’axe des X est parallèle avec les rangées d’hexagones. Ce qui nous donne :
Pour les curieux, le code utilisé pour générer l’image des coordonnées est disponible ici (trop long pour être sur la page), et une animation de l’algo est visible là.
Position d’une case
Nous disposons maintenant un système de coordonnées pour les cases. Voyons maintenant comment faire une translation de ce système de coordonnées vers celui du canvas.
- La position d’une case est ici définie par les coordonnées du centre de celle ci.
- Le système de coordonnées cartésiennes utilisé pour la carte sera ci dessous appelé "plan hexagonal".
- Le système de coordonnées orthonormé utilisé par le canvas sera ci dessous appelé le "plan canvas". Le point d’origine du canvas est en haut à gauche, ce qui fait que l’axe des Y est inversé.
- "A" désigne ici la longueur d’un côté d’un hexagone.
Écart vertical
Les axes Y du plan hexagonal (en vert) et du plan canvas sont parallèles, donc rien de sorcier.
Les coordonnées "plan hexagonal" [1;0] et [0;0] sont séparées par une distance canvas de [ 2 * A * cos(30°) , 0].
Écart horizontal
Là par contre, ça coince un peu. L’axe X du canvas est horizontal, alors que celui du plan hexagonal (en rouge) non.
Quelle distance sépare les coordonnées "plan hexagonal" [0;0] et [0;1], en équivalent canvas ?
- y : A * cos(30°)
- x : A + A * sin(30°)
Pratiquons
Code
//ici le code traçant les hexagones et les lignes de repère *snip* (...) //point d'origine du plan canvas, defini manuellement var origin_y = 5 * cos_unit; // 3eme bloc en partant du haut (donc 2.5 block de haut pour être au milieu) var origin_x = sin_unit + unit/2; //centre du 1er bloc en partant de la gauche pinceau.beginPath(); pinceau.font = '12pt Calibri'; pinceau.textAlign = 'center'; pinceau.fillStyle = 'green'; var coord = coordinates_hexa_to_canvas(0, 0 ) pinceau.fillText("0+0", coord.x, coord.y); //du texte, mais ça pourrait être une image ou autre. coord = coordinates_hexa_to_canvas(1, 2 ) pinceau.fillText("y1;x2", coord.x, coord.y); coord = coordinates_hexa_to_canvas(3, 2 ) pinceau.fillText("y3;x2", coord.x, coord.y); coord = coordinates_hexa_to_canvas(4, 4) pinceau.fillText("y4;x4", coord.x, coord.y); function coordinates_hexa_to_canvas(wanted_y, wanted_x ) { //variables "globales" utilisées : cos_unit, sin_unit, unit, origin_y, origin_x var coordinates = []; //vertical part. canvas system has Y inverted, so goes down as hexa coordinates go up. coordinates.y = origin_y - (wanted_y * (2 * cos_unit)); //"horizontal" part coordinates.y += (wanted_x * cos_unit); coordinates.x = origin_x + (wanted_x * (unit + sin_unit)); return coordinates; }
Affichage
Et voilou !