If you don't mind using canvas to check if a cell is already occupied, you can "walk" in a spiral around the already present cells, trying to keep the right side as much as possible. It reminds me the LOGO turtle.
The cell moves along direction
dir (in degrees) of a step of length
diam (diameter of circles). After placing itself it calculates the next step.
It checks first if the space at the "right side-behind" (corresponding to 4 o'clock) is free. If it is free the new direction (previous direction + 120 degrees) is accepted.
Otherwise it checks the "right side-front" position (corresponding to 2 o'clock). If it is free, the new walking direction is previous direction+60 degrees.
If both cells are not free, the walk proceed straight ahead (there is always space there).
This is the code for 100 circles:
- int numSteps = 100; // number of circles
- float diam = 30; // diameter of each circle
- float posX = 200; // initial position of central circle
- float posY = 200;
- float dir = 0; // walking direction (in degrees)
- size(400, 400);
- background(255);
- smooth();
- PFont f = createFont("Arial", 12);
- textFont(f);
- textAlign(CENTER, CENTER);
- ellipseMode(CENTER);
- for (int i=0; i<numSteps; i++) {
- // paint the circle
- colorMode(HSB, 360, 100, 100);
- fill(i*5, 100, 100);
- ellipse(posX, posY, diam*.9, diam*.9);
- colorMode(RGB, 255, 255, 255);
- // and its ID text
- fill(0);
- text(i+1, posX, posY);
- // calculate next position
- // is 4 o'clock cell free?
- float tempX = posX + diam*cos(radians(dir+120));
- float tempY = posY + diam*sin(radians(dir+120));
- if (get(int(tempX), int(tempY)) == color(255)) {
- // yes, it is free, move there and change heading direction
- dir += 120;
- }
- else { // is 2 o'clock cell free?
- tempX = posX + diam*cos(radians(dir+60));
- tempY = posY + diam*sin(radians(dir+60));
- if (get(int(tempX), int(tempY)) == color(255)) {
- // yes, it is free, move there and change heading direction
- dir += 60;
- }
- else { // no, move straight ahead without changing direction
- tempX = posX + diam*cos(radians(dir));
- tempY = posY + diam*sin(radians(dir));
- }
- }
- // move to the next position
- posX = tempX;
- posY = tempY;
- }
An alternative is to combine some Net's references.
I didn't try them and I'm not sure if they can solve your problem.
you find how to convert hexagons coordinates to (x,y).
Nice day!
Alessandro