Darkoneko's Weblog

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

[html5] carte 3 – hexagones et repère carthésien

Posted by DarkoNeko sur dimanche 30 juin 2013

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 :

hexagon-mapx

hexagon-map5
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.

hexagon-translation-canvas2         hexagon-angles

É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;
}

(code complet ici)

Affichage

hexagon-map-translation

Et voilou !

Sorry, the comment form is closed at this time.