Selecting a number from an array, only allowing certain numbers to follow

Hi all,
Today I’m trying to create another work of generative art. the goal is simple, to generate simple curves and lines that connect to each other, but only connecting curves and lines are allowed to be injected after the first one is generated. If the lines and curves are ‘closing’ the next possible connection, a new one is chosen. See this illustration:

Now what I did in a tryout sketch, was to load the allowed possibilities in a 2D-array, this worked really well but it lacked a couple of things and I wanted to redo it. For example, my last sketch only used a combination that allowed for 3 possible next shapes. As you can see in the illustration, now the next possible shapes are sometimes 4, sometimes 3, sometimes 2 and sometimes only 1.

The arcs are made in such a way that the center of the visible part becomes the center of the arc. All values are relative to each other so changing the base values changes everything else with it.

To get a feeling for what I’m trying to do, see and test out my test sketch here:

float x = 0;
float y = 0;
float spacing = 20;
float lineSpc = spacing/2;
float radius = spacing*2;
int a = floor(random(1));
int b = floor(random(3));

void setup() {
  background(51);
  size(600, 600);
  pixelDensity(displayDensity());
  noFill();
  strokeWeight(3);
  stroke(255);
}

int[][] options = {   {1, 2, 3}, 
                      {0, 4, 5}  };

void draw() {
  float rnd = options[a][b];

  if (rnd == 0) {
    //A1
    float xx = -lineSpc;
    float yy = -lineSpc;
    arc(x + spacing + xx, y + spacing + yy, radius, radius, radians(0), radians(90), OPEN);
    println(a + " & " + b + " = " + options[a][b]);
    a = 0;
    b = floor(random(3));
  } else if (rnd == 1) {
    //A2
    float xx = lineSpc;
    float yy = -lineSpc;
    arc(x + spacing + xx, y + spacing + yy, radius, radius, radians(90), radians(180), OPEN);
    println(a + " & " + b + " = " + options[a][b]);
    a = 1;
    b = floor(random(3));
  } else if (rnd == 2) {
    //A3
    println(a + " & " + b + " = " + options[a][b]);
    line(x+lineSpc, y+lineSpc, x+lineSpc, y+spacing+lineSpc);
    a = 0;
    b = floor(random(3));
  } else if (rnd == 3) {
    //B1
    float xx = lineSpc;
    float yy = lineSpc;
    arc(x + spacing + xx, y + spacing + yy, radius, radius, radians(180), radians(270), OPEN);
    println(a + " & " + b + " = " + options[a][b]);
    a = 1;
    b = floor(random(3));
  } else if (rnd == 4) {
    //B2
    float xx = -lineSpc;
    float yy = lineSpc;
    arc(x + spacing + xx, y + spacing + yy, radius, radius, radians(270), radians(360), OPEN);
    println(a + " & " + b + " = " + options[a][b]);
    a = 0;
    b = floor(random(3));
  } else if (rnd == 5) {
    //B3
    line(x+lineSpc, y+lineSpc, x+spacing+lineSpc, y+lineSpc);
    println(a + " & " + b + " = " + options[a][b]);
    a = 1;
    b = floor(random(3));
  }
  
  x = x + spacing;
  if (x > width-radius) {
    x = 0;
    y = y + spacing;
  }
  if (y > height-radius) {
    noLoop();
  }
}

See the effect here:

I am trying to create an artwork with a certain aesthetic and am pretty new to processing, only working with it for a few weeks without prior experience in this kind of coding so I hope this script is okay. I know it’s not as efficient as it could be, efficiency hinders my creative process in the sketching stage but it would also be nice to learn how I can make these scripts smaller because eventually I lose oversight because my written scripts are very long for the simple tasks they perform.

My question comes down to, how would I best select one value from the array with eight initial possibilities, that after the initial start only allows for the ‘next few allowed values’?

Are 2D-arrays the way to go here, or would it be best to just hardcore these values in?

I am very grateful for your time and expertise. Thanks in advance and I hope I am not wasting anyone’s time.

1 Like

I wanted to update this question with a possible solution I found myself, but I think this might be a really huge workaround.

Second to that, I realized that I also would have to write code that compares the connections with each other in the Y-direction. Now I’m not asking for anyone to write the code for me, but are there techniques I can read about that I can try out that will help me make a comparison in both the X and Y direction without having to do all of this manually?

Partial solution:

float x = 0;
float y = 0;
float spacing = 30;
float lineSpc = spacing/2;
float radius = spacing*2;
int a = 0;
int b = floor(random(4));

void setup() {
  background(51);
  size(600, 600);
  pixelDensity(displayDensity());
  noFill();
  strokeWeight(spacing/6.67);
  stroke(255);
  strokeCap(PROJECT);
}

int[][] options = { {1, 2, 4, 6}, 
                    {0, 5}, 
                    {3, 7},
                    {1, 2},
                    {6},
                    {0},
                    {1, 2},
                    {3}  };

void draw() {
  float rnd = options[a][b];

  if (rnd == 0) {
    //A0
    float xx = -lineSpc;
    float yy = -lineSpc;
    arc(x + spacing + xx, y + spacing + yy, radius, radius, radians(0), radians(90), OPEN);
    println(a + " & " + b + " = " + options[a][b]);
    a = 0;
    b = floor(random(3));
  } else if (rnd == 1) {
    //A1
    float xx = lineSpc;
    float yy = -lineSpc;
    arc(x + spacing + xx, y + spacing + yy, radius, radius, radians(90), radians(180), OPEN);
    println(a + " & " + b + " = " + options[a][b]);
    a = 1;
    b = floor(random(2));
  } else if (rnd == 2) {
    //A2
    float xx = lineSpc;
    float yy = lineSpc;
    arc(x + spacing + xx, y + spacing + yy, radius, radius, radians(180), radians(270), OPEN);
    println(a + " & " + b + " = " + options[a][b]);
    a = 2;
    b = floor(random(2));
  } else if (rnd == 3) {
    //A3
    float xx = -lineSpc;
    float yy = lineSpc;
    arc(x + spacing + xx, y + spacing + yy, radius, radius, radians(270), radians(360), OPEN);
    println(a + " & " + b + " = " + options[a][b]);
    a = 3;
    b = floor(random(2));
  } else if (rnd == 4) {
    //B0
    line(x+spacing+lineSpc, y+lineSpc, x+spacing+lineSpc, y + spacing+lineSpc);
    println(a + " & " + b + " = " + options[a][b]);
    a = 4;
    b = floor(random(1));
  } else if (rnd == 5) {
    //B1
    line(x+lineSpc, y + spacing+lineSpc, x + spacing+lineSpc, y + spacing+lineSpc);
    println(a + " & " + b + " = " + options[a][b]);
    a = 5;
    b = floor(random(1));
  } else if (rnd == 6) {
    //B2
    line(x+lineSpc, y+lineSpc, x+lineSpc, y + spacing+lineSpc);
    println(a + " & " + b + " = " + options[a][b]);
    a = 6;
    b = floor(random(2));
  } else if (rnd == 7) {
    //B3
    line(x+lineSpc, y+lineSpc, x + spacing+lineSpc, y+lineSpc);
    println(a + " & " + b + " = " + options[a][b]);
    a = 7;
    b = floor(random(1));
  }
  
  x = x + spacing;
  if (x > width-radius) {
    x = 0;
    y = y + spacing;
  }
  if (y > height-radius) {
  //if (y > 10) {
    noLoop();
  }
}
  • Is your goal to do 10-print style population of the grid, L-R, T-B? So you check each tile before you place it down? Or do you want to be able to grow, flood-fill, or change the tile grid in random directions?
  • Is it possible for you to create an impossible tile? That is, are there any combinations A B such that for:
A
B C

…there is no solution C?

Your problem space is somewhat related to Conway’s Game of Life implementations, of which there are many in Processing. Those are more complicated, but some of the considerations are the same.

You might also be interested in the tiled model of the Wave Collapse Function – the algorithm is quite complex, but it takes a list of tiles and connections (exactly like you specify above) and then generates a solution – the solving process can also be animated. See the “tiled” section partway down in this discussion: