A Circle tile instead of square one


#1

here’s my hexagonal tiling in a square shape, I would like to convert the square shape into a circle one, can anyone help me?

float unitSize = 15;
float eqTriH = 0.8660254;
int w = 600;
int h = 600;
int cellsX = int(w/(unitSize*3));
int cellsY = int(h/(unitSize*eqTriH*2+eqTriH));
float[][] terrain;
int cols, rows;
int scl=20;
float flying=0;
import processing.sound.*;
Amplitude amp;
AudioIn in;
void setup() {
  fullScreen(P3D);
  cols=w/scl;
  rows=h/scl;
  terrain=new float[cols][rows];
  smooth();
  in = new AudioIn(this, 0);
  in.start();
  amp = new Amplitude(this);

  amp.input(in);
}

void draw() {
  background(51);
  flying-=0.01;
  float yoff=flying;
  for (int y=0; y<rows; y++) {
    float xoff=0;
    for (int x=0; x<cols; x++) {
      terrain[x][y]=map(noise(xoff, yoff), 0, 1, -50, 50);
      xoff+=0.2;
    }
    yoff+=0.2;
  }
  translate(660, 240);
  float vol = amp.analyze();
  for (int i = 0; i < cellsX; i++) {
    for (int j = 0; j < cellsY; j++) {
      noFill();
      stroke(255);
      strokeWeight(0.8);
      beginShape();
      for (int k = 0; k < 6; k++) {
        vertex(unitSize+i*unitSize*3+cos(TWO_PI/6*k)*unitSize, 
          unitSize*eqTriH+j*unitSize*2*eqTriH+sin(TWO_PI/6*k)*unitSize, 
          terrain[i][j]+random(-vol*600, vol*600));
      }
      endShape(CLOSE);
      noFill();
      stroke(255);
      strokeWeight(0.8);
      beginShape();
      for (int k = 0; k < 6; k++) {
        vertex(unitSize*2.5+i*unitSize*3+cos(TWO_PI/6*k)*unitSize, 
          unitSize*eqTriH*2+j*unitSize*2*eqTriH+sin(TWO_PI/6*k)*unitSize, 
          terrain[i][j]+random(-vol*600, vol*600));
      }
      endShape(CLOSE);
    }
  }
}


#2

There are several ways you could approach this problem. One is to create a mask that tells you whether to draw a tile or not.

For example, you could use the circle-point collision algorithm to check whether or not a tile on your grid would fall inside a circle.

So, given this function:

// POINT/CIRCLE
boolean pointCircle(float px, float py, float cx, float cy, float r) {

  // get distance between the point and circle's center
  // using the Pythagorean Theorem
  float distX = px - cx;
  float distY = py - cy;
  float distance = sqrt( (distX*distX) + (distY*distY) );

  // if the distance is less than the circle's
  // radius the point is inside!
  if (distance <= r) {
    return true;
  }
  return false;
}

…we are going to test each cell x,y against a circle of radius cellsX / 2.0.

So, for example, inside your i,j loop, wrap the rendering of a cell in something like this:

 if (pointCircle(i, j, cellsX/2.0, cellsY/2.0, cellsX/2.0)) {

A different approach would be to not use a nested x,y loop for rending, and instead either use one loop that winds out from the center, or a loop for nested rings of hexagons. This however would change your render order, which would change your audio data mapping. For discussion of hex rings and winding, see:


#3

#4

Interesting, @Chrisir !

Looks like this approach is to create a hexagon class, save an x,y in each hexagon object, and populate them manually in strips by marching through a series of offset for-loops.

The only thing I don’t like about this approach is that it is hard-coded for one exactly one size, and there is no way to change the board size without rewriting the whole function. That works great for Settlers of Catan, but not as well for a music visualizer.


#5

thanks this was so helpful