Panal de abejas

facebook-svg gplus-svg twitter-svg

A continuación vamos a dibujar un patrón que imita un panal de abejas. Un panal es una estructura formada por celdillas hexagonales que comparten paredes. Por lo tanto dibujamos una por una las celdillas hexagonales, dejando un pequeño espacio ( la pared ) entre ellas. En el siguiente ejemplo el espaciado de celda es de 1 px ( var espaciado = 1; ) pero puede ser modificado fácilmente, sin que esto afecte la estructura del panal.

Como dibujar un hexágono

Empezamos definiendo algunas variables necesarias:

// El radio:
var R = 30;
// El diámetro:
var D = R*2;
hexagono
hexagonos

Ya que la segunda fila de celdillas esta desplazada tanto en x ( horizontalmente ) como en y ( verticalmente ) relativamente a la fila anterior, calculamos dos variables más:

// El desplazamiento en y:
var yoffset = Math.sqrt(3) / 2 * R;
// El desplazamiento en x:
var xoffset = (3*R)/2;

Para unas juntas perfectas y sin costuras recalculamos el tamaño del <canvas>. El ancho como el alto del <canvas> tiene que ser un múltiplo del diámetro.

canvas.width = Math.round(canvas.width/D)*D;

El alto del <canvas> tiene que ser un múltiplo de la altura del hexágono.

canvas.height = Math.round(canvas.height/(2*yoffset))*(2*yoffset);

También definimos el color de relleno de las celdillas (fillStyle), el color de los bordes (strokeStyle) y el ancho de los bordes (lineWidth).

Para que el código sea más eficiente escribimos una función que dibuja los hexágonos uno por uno. Es importante redefinir dentro de la función el valor de canvas y del contexto ctx.


function dibujarHexagon(X, Y, R) {
  var canvas = document.getElementById("lienzo");
  var ctx = canvas.getContext("2d");

  var rad = (Math.PI / 180) * 60;
  ctx.beginPath();
  for (var i = 0; i < 6; i++) {

    x = X + R * Math.cos(rad * i);
    y = Y + R * Math.sin(rad * i);
    ctx.lineTo(x, y);
  }
  ctx.closePath();
  ctx.fill();
  ctx.stroke();
}

Para entender mejor la función dibujarHexagono() vea como dibujar un hexágono

Utilizamos un bucle for (for loop) para dibujar las primeras dos filas de celdillas, y otro bucle for (for loop) para repetirlo todo en y.

Su navegador no soporta canvas :( 

var canvas = document.getElementById("lienzo");
if (canvas && canvas.getContext) {
  var ctx = canvas.getContext("2d");
  if (ctx) {
    var R = 30;
    var D = R * 2;

    var yoffset = Math.sqrt(3) / 2 * R;
    var xoffset = (3 * R) / 2;
    // para unas juntas perfectas y sin costuras recalculamos el tamaño del canvas								
    canvas.width = Math.round(canvas.width / D) * D;
    canvas.height = Math.round(canvas.height / (2 * yoffset)) * (2 * yoffset);

    ctx.fillStyle = "orange";
    ctx.strokeStyle = "white";
    ctx.lineWidth = 1;

    for (Y = 0; Y <= canvas.height + R; Y += 2 * yoffset) {
      for (X = 0; X <= canvas.width + R; X += 2 * xoffset) {
        //1-a fila
        dibujarHexagon(X, Y, R);
        //2-a fila
        dibujarHexagon(X + xoffset, Y + yoffset, R)
      }
    }
  }
}	

function dibujarHexagon(X, Y, R) {
  var canvas = document.getElementById("lienzo");
  var ctx = canvas.getContext("2d");

  var rad = (Math.PI / 180) * 60;
  ctx.beginPath();
  for (var i = 0; i < 6; i++) {

    x = X + R * Math.cos(rad * i);
    y = Y + R * Math.sin(rad * i);
    ctx.lineTo(x, y);
  }
  ctx.closePath();
  ctx.fill();
  ctx.stroke();
}
Su navegador no soporta canvas :(

Para recuperar la imagen utilice toDataURL

var url = canvas.toDataURL();

Nota: Firefox nos permite abrir y guardar la imagen generada haciendo clic con el botón derecho del ratón, y escogiendo la opción deseada.