draw a hexagon of hexagons in p5.js

Viewed 84

I am trying to create a hexagon made out of hexagon cells in p5.js.

I would like the algorithm to receive the following as input:

  1. number of hexagon cells in the first row
  2. total hexagon cells to draw

This is the code I have so far but it is not drawing the shape the way I want to.

// declare fixed variables
let diam = 30;
let total_hex = 30;
let diagonal = 7;
let first_row = 4;
let side = first_row;

// declare dependent variables
let radius = diam / 2;
let upper_half = side - 1;
let rows = upper_half + side;

function setup() {
  createCanvas(700, 700);
}

// draw
function draw() {
  background("#ffae5");
  noFill();
  strokeWeight(2);
  stroke("#ffb703");

  // start counters
  // row_counter = rows;
  counter = 0;
  row_cells = first_row;

  push();
  translate(200, 200);

  for (let j = 0; j < rows; j++) {
    for (let i = 0; i < row_cells; i++) {

      push();
      translate(-j * (radius + radius / 2 + radius / 4), 0);

      if (diagonal > i) {
        console.log(diagonal, i);
        push();
        translate(i * 2 * diam - (i * radius) / 2, 3 * j * (diam / 2));
        polygon(0, 0, diam, 6);
        pop();

      }
      pop();
    }

    if (rows < j) {
      row_cells -= 1;
    }
    if (rows > j) {
      row_cells += 1;
    }
  }
  pop();
}

function polygon(x, y, radius, npoints) {
  let angle = TWO_PI / npoints;
  beginShape();
  for (let a = 0; a < TWO_PI; a += angle) {
    let sx = x + sin(a) * radius;
    let sy = y + cos(a) * radius;
    vertex(sx, sy);
  }
  endShape(CLOSE);
}

Specifically, the hexagons from the bottom half of the shape appear to be shifted by some parameter I still can't figure out. Here's the link to the p5.js online editor.

What am I missing here? Thanks!

2 Answers

I logged i, j at each cell to determine the position.

enter image description here

Now if you look at the cells you want to remove, you will see that these cells are: i < 3 && j > 3 && j - i > 3.

enter image description here

So if you simply want to remove these cells, you could change your if (diagonal > i) to if (diagonal > i && !(i < 3 && j > 3 && j - i > 3))) or parametrize that 3 to be a dependent variable to Math.floor(diagonal/2) to make something like:

//declare fixed variables
let diagonal = 7;
...

//declare dependent variables
const bottomLeftThreshold = Math.floor(diagonal/2);
...

const bottomLeft = i < bottomLeftThreshold && j > bottomLeftThreshold && j - i > bottomLeftThreshold

if (diagonal > i && !(bottomLeft))
  ...

Now the code is much more readable and modularized.

I did some tweaks to @cSharp's code snippet (see first answer) here and there, and ended up making the code flexible enough so it can adapt to any number of hexagons and sizes.

Below are the "fixed" and "dependent" variables I declared to draw the hexagon as well as the draw() function. I had to do some auxiliary calculations to get the diagonal and side sizes here.

// declare data variables
let year_1920 = 21;
let year_2019 = 73;


// declare fixed variables
let diam = 30;
let total_hex = year_2019;
let diagonal = 11;
let first_row = 6;
let side = first_row;

// declare dependent variables
let radius = diam / 2;
let upper_half = side - 1;
let rows = upper_half + side;

function draw() {
  background("#ffae5");
  noFill();
  strokeWeight(1.2);
  stroke("#ffb703");

  // start counters
  yellow = 0;
  counter = 0;
  row_cells = first_row;

  push();
  translate(200, 100);

  for (let j = 0; j < rows; j++) {
    for (let i = 0; i < row_cells; i++) {
      if (yellow >= year_1920) {
        stroke(255);
        fill("#ffb703");
      }
      yellow++;

      if (counter >= total_hex) {
        noStroke();
        noFill();
      }

      push();
      translate(-j * (radius + radius / 2 + radius / 4), 0);

      if (
        diagonal > i &&
        !(i < upper_half && j > upper_half && j - i > upper_half)
      ) {
        push();
        translate(i * 2 * diam - (i * radius) / 2, 3 * j * (diam / 2));
        polygon(0, 0, diam, 6);
        pop();

        counter++;
      }
      pop();
    }

    if (rows > j) {
      row_cells++;
    }
  }

  pop();
}

Related