# General rule for shape arrangement

**URL:** https://discourse.processing.org/t/general-rule-for-shape-arrangement/40498
**Category:** Project Guidance
**Created:** [January 7, 2023, 3:29pm UTC](https://discourse.processing.org/t/general-rule-for-shape-arrangement/40498 "2023-01-07T15:29:50Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![paulgoux](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@paulgoux](https://discourse.processing.org/u/paulgoux)
#### Post date: [January 7, 2023, 3:29pm UTC](https://discourse.processing.org/t/general-rule-for-shape-arrangement/40498/1 "2023-01-07T15:29:50Z")

</div>

As the title implies, is there a general rule that I can apply instead of using offset and padding to make a grid.

as it stands I try to make a grid using the following code

```auto
for (int i=0; i<sides; i++) {
      float thetab = theta * i;
      float thetac = theta * i+theta;

      walls[i] = true;
      walls2[i] = true;
      wallsBackup[i] = true;
      node_info.add(new Integer[3]);
      edge.add(new PVector[2]);
      //println("edge init", x, y);
      edge.get(i)[0] = new PVector(x+w/2*sin(thetab), y+h/2*cos(thetab));
      edge.get(i)[1] = new PVector(x+w/2*sin(thetac), y+h/2*cos(thetac));
      vertex[i]= new PVector(x+w/2*sin(thetac), y+(h/2)*cos(thetac));
      length = dist(x+w/2*sin(thetab), y+h/2*cos(thetab), x+w/2*sin(thetac), y+h/2*cos(thetac));
    }

```

I have to add some extra rules to make it more palatable and even then it doesnt work for every grid all the time.

```auto
if (sides>4)
      if (pos==1) {
        x = (xpos-0.5) *g.tileWidth+w-(xpos*w/sides+xpadding)+xoffset;
      } else {
        x = (xpos) *g.tileWidth+w-(xpos*w/sides+xpadding)+xoffset;
      } else x = (xpos) *g.tileWidth;

```

and this is the result  
 ![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/b/c/bc32dfa4f7942dfc54d041d2c12ff7c346c6c9bb.png)

then when changing number of sides

![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/0/6/06316d28be85e47f355ca475576a49b921d88d84.png)

---

<div class="post-metadata">

### Author: ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)
#### Post date: [January 7, 2023, 7:21pm UTC](https://discourse.processing.org/t/general-rule-for-shape-arrangement/40498/2 "2023-01-07T19:21:32Z")

</div>

“make a grid” is a bit too ambiguous. Are you trying to make tilings of the plane with an arbitrary number of tiles of arbitrary shapes with arbitrary concavities with any of the wallpaper groups for symmetry? Or are you just trying to tile with hexagons or squares?

For hexagonal or triangular tilings, you need a 1/2 offset for odd rows (or for odd columns). Or you need to double-up your tiles within a rectangular grid – draw both an even and an odd hex for each grid cell.

---

<div class="post-metadata">

### Author: ![scudly](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/scudly/32/5597_2.png) [@scudly](https://discourse.processing.org/u/scudly)
#### Post date: [January 7, 2023, 7:47pm UTC](https://discourse.processing.org/t/general-rule-for-shape-arrangement/40498/3 "2023-01-07T19:47:04Z")

</div>

Actually, there is a way to draw both hex and diamond tiles with a single method by drawing only the even-coordinate tiles – ones for which i+j is even.

Take a look at [https://www.shadertoy.com/view/7tKfzz](https://www.shadertoy.com/view/7tKfzz).

Below is some code I wrote a while ago when someone posted about making a simple Settlers of Catan board layout. If you set Sx and Sy equal to each other, you could re-write the `catan()` function to draw a diamond grid if you get the scale correct.

```auto
void polygon(float x, float y, float radius, int npoints) {
  beginShape();
  for( int i=0; i<npoints; i++ ) {
    float a = TAU * i / npoints;
    float sx = x + sin(a) * radius;
    float sy = y - cos(a) * radius;
    vertex(sx, sy);
  }
  endShape(CLOSE);
}

float Sx = sqrt(3)/2, Sy = 1.5;
class HexPos {
  float dx, dy;
  int i, j;
  HexPos( float dx, float dy, int i, int j ) {
    this.dx = dx; this.dy = dy; this.i = i; this.j = j;
  }
}

// https://www.redblobgames.com/grids/hexagons/#coordinates-doubled
// https://www.redblobgames.com/grids/hexagons/#conversions-doubled
HexPos hexParity( float x, float y ) {
  int i = floor( x / Sx );
  int j = floor( y / Sy );
  int parity = (i+j)&1;
  float lx = x - Sx * i;
  float ly = y - Sy * (j+parity);
  float rx = x - Sx * (i+1);
  float ry = y - Sy * (j+1-parity);
  return ( lx*lx+ly*ly < rx*rx+ry*ry ) ?
    new HexPos( lx, ly, i, j+parity ) :
    new HexPos( rx, ry, i+1, j+1-parity );
}

void catan( int n ) {
  for( int j=-n; j<=n; j++ )
    for( int i=-2*n+abs(j); i<=2*n-abs(j); i+=2 ) {
      fill( random(1,6), random(5,8), random(5,9) );
      polygon( Sx*i, Sy*j, 0.98, 6 );
    }
}

float viewScale;
HexPos mouseHex;

int N = 6;

void setup() {
  size( 600, 600 );
  viewScale = width/(4*N+2);
  mouseHex = new HexPos(0,0,10,10); // off screen
  colorMode( HSB, 10, 10, 10, 10 );
  noStroke();
  noLoop();
}

void draw() {
  background( 0 );
  translate( width/2, height/2 );
  scale( viewScale );
  randomSeed( 5 );
  catan( N );
  fill( 0, 0, 10, 5 );
  polygon( mouseHex.i*Sx, mouseHex.j*Sy, 0.9, 6 );
}

void mouseMoved() {
  mouseHex = hexParity( (mouseX-width/2)/viewScale, (mouseY-height/2)/viewScale );
  redraw();
}

```

---

<div class="post-metadata">

### Author: ![paulgoux](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@paulgoux](https://discourse.processing.org/u/paulgoux)
#### Post date: [January 8, 2023, 1:24pm UTC](https://discourse.processing.org/t/general-rule-for-shape-arrangement/40498/4 "2023-01-08T13:24:13Z")

</div>

Thanks I’ll take a look later. I’m guessing there are implications for the id that’s returned but some further calculations can be made to take that into account. Ie recount the grid with only odd or even numbers and that should return the id.

---

<div class="post-metadata">

### Author: ![paulgoux](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@paulgoux](https://discourse.processing.org/u/paulgoux)
#### Post date: [January 9, 2023, 11:11am UTC](https://discourse.processing.org/t/general-rule-for-shape-arrangement/40498/5 "2023-01-09T11:11:09Z")

</div>

found one for 6 sided, where w is tileWidth

```auto
if (sides>2)
      if (pos==1) {
        x = xoffset+(xpos-0.5) *(g.tileWidth-w*sin(theta)/sides)+-w/2*sin(theta)-(0);
      } else {
        x = xoffset+(xpos) *(g.tileWidth-w*sin(theta)/sides)+-w/2*sin(theta)-(0);
      } else x = (xpos) *g.tileWidth;

    y = yoffset+(ypos)*(h*sin(theta)-h*sin(theta)/sides);

```

![image](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/3X/6/a/6ae35e04afe3bda314483268c0f3567034215cc6.png)
