Avoiding tile overlap (of colorful plastic toy shapes)

Below is code I’m working on to display those little plastic toy shapes (hexagon, triangle, square, etc…) and I wanted to find a way to prevent a new shape from overlapping previous ones. So far I have the shapes displaying correctly, and I’m saving each new vertex in an array (with the kind of shape it is part of).

I considered creating a simple black/white image (that would not be displayed) that keeps track of the area used and as a new vertex is proposed checking it against that stored image. However such an image would keep all the edge vertices as well, and those edges should not be off limits.
Any ideas of how to check each new vertex to make sure it isn’t overlapping a previous shape?

Also any other suggestions to tweak my code are welcome!

/*program to display colorful shapes (based on plastic toy)
goals:
with no overlapping shapes
with no shape touching another shape of the same kind (including at corners)
filling the screen
*/



float x0, y0;
float unit = 100; //size for shapes
float theta0, theta;
int shape;
int index = 0; //for vertex array

boolean check = true; //for checking if proposed vertex passes certain tests 
boolean[] shapes = new boolean[6]; //used to pick a shape until each has been used

Vertex[] vertices = new Vertex[1000]; //guessed maximum number of vertices



void setup() {
  size(700,700);
  //fullScreen();
  frameRate(1);
  background(0);
  //initialize shapes booleans, no shape has been picked yet
  for (int i = 0; i < shapes.length; i++) {
    shapes[i] = false;
  }
  
  
  x0 = (width/2); //random(width);
  y0 = (height/2); //random(height);
  pickShape();
  
  theta0 = 360; //random(360);
  smooth();
  noStroke();
}

void draw() {

  drawShape();
  if (check == false) {  
    check = true;      //reset check
  }
  
  int i = int(random(index)); //picks a random vertex previously used
  x0 = vertices[i].x;
  y0 = vertices[i].y;
  theta0 = theta0 + int(random(12)) * 30;
  if (theta0 > 360) theta0 = theta0 - 360; //keep theta within 360
  
}


//___________________function that draws shapes___________________ 
void drawShape() {
  
  float x1, y1, x2, y2, x3, y3, x4, y4, x5, y5;
  int rotation; //used for different rotations
  
  theta = theta0;
  
  while (check) {
    if (shape == 0) { //yellow hexagon
    
      x1 = x0 + cos(radians(theta)) * unit;
      y1 = y0 + sin(radians(theta)) * unit;
      checkVertex(x1, y1);
      if (check == false) break;
      vertices[index] = new Vertex(x1, y1, shape); stepIndex();
      theta = theta + 60;
      
      x2 = x1 + cos(radians(theta)) * unit;
      y2 = y1 + sin(radians(theta)) * unit;
      checkVertex(x2, y2);
      if (check == false) break;
      vertices[index] = new Vertex(x2, y2, shape); stepIndex();
      theta = theta + 60;
      
      x3 = x2 + cos(radians(theta)) * unit;
      y3 = y2 + sin(radians(theta)) * unit;
      checkVertex(x3, y3);
      if (check == false) break;
      vertices[index] = new Vertex(x3, y3, shape); stepIndex();
      theta = theta + 60;
      
      x4 = x3 + cos(radians(theta)) * unit;
      y4 = y3 + sin(radians(theta)) * unit;
      checkVertex(x4, y4);
      if (check == false) break;
      vertices[index] = new Vertex(x4, y4, shape); stepIndex();
      theta = theta + 60;
      
      x5 = x4 + cos(radians(theta)) * unit;
      y5 = y4 + sin(radians(theta)) * unit;
      checkVertex(x5, y5);
      if (check == false) break;
      vertices[index] = new Vertex(x5, y5, shape); stepIndex();
    
      fill (255, 255, 0);
      beginShape();
      vertex(x0, y0);
      vertex(x1, y1);
      vertex(x2, y2);
      vertex(x3, y3);
      vertex(x4, y4);
      vertex(x5, y5);
      endShape(CLOSE);
      
      pickShape();
      
    } else if (shape == 1) { //green triangle
      
      x1 = x0 + cos(radians(theta)) * unit;
      y1 = y0 + sin(radians(theta)) * unit;
      checkVertex(x1, y1);
      if (check == false) break;
      vertices[index] = new Vertex(x1, y1, shape); stepIndex();
      theta = theta + 120;
      
      x2 = x1 + cos(radians(theta)) * unit;
      y2 = y1 + sin(radians(theta)) * unit;
      checkVertex(x2, y2);
      if (check == false) break;
      vertices[index] = new Vertex(x2, y2, shape); stepIndex();
    
      fill (0, 255, 0);
      beginShape();
      vertex(x0, y0);
      vertex(x1, y1);
      vertex(x2, y2);
      endShape(CLOSE);
      
      pickShape();
      
    } else if (shape == 2) { //orange square
      
      x1 = x0 + cos(radians(theta)) * unit;
      y1 = y0 + sin(radians(theta)) * unit;
      checkVertex(x1, y1);
      if (check == false) break;
      vertices[index] = new Vertex(x1, y1, shape); stepIndex();
      theta = theta + 90;
      
      x2 = x1 + cos(radians(theta)) * unit;
      y2 = y1 + sin(radians(theta)) * unit;
      checkVertex(x2, y2);
      if (check == false) break;
      vertices[index] = new Vertex(x2, y2, shape); stepIndex();
      theta = theta + 90;
      
      x3 = x2 + cos(radians(theta)) * unit;
      y3 = y2 + sin(radians(theta)) * unit;
      checkVertex(x3, y3);
      if (check == false) break;
      vertices[index] = new Vertex(x2, y2, shape); stepIndex();
    
      fill (255, 127, 0);
      beginShape();
      vertex(x0, y0);
      vertex(x1, y1);
      vertex(x2, y2);
      vertex(x3, y3);
      endShape(CLOSE);
      
      pickShape();
      
    } else if (shape == 3) { //red half hexagon (with 5 rotations)
      
      rotation = int(random(5));
      
      if (rotation == 1) {
        x1 = x0 + cos(radians(theta)) * unit;
        y1 = y0 + sin(radians(theta)) * unit;
        checkVertex(x1, y1);
        if (check == false) break;
        vertices[index] = new Vertex(x1, y1, shape); stepIndex();
        theta = theta + 120;
        
        x2 = x1 + cos(radians(theta)) * unit;
        y2 = y1 + sin(radians(theta)) * unit;
        checkVertex(x2, y2);
        if (check == false) break;
        vertices[index] = new Vertex(x2, y2, shape); stepIndex();
        theta = theta + 60;
        
        x3 = x2 + cos(radians(theta)) * unit;
        y3 = y2 + sin(radians(theta)) * unit;
        checkVertex(x3, y3);
        if (check == false) break;
        vertices[index] = new Vertex(x3, y3, shape); stepIndex();
        theta = theta + 60;
        
        x4 = x3 + cos(radians(theta)) * unit;
        y4 = y3 + sin(radians(theta)) * unit;
        checkVertex(x4, y4);
        if (check == false) break;
        vertices[index] = new Vertex(x4, y4, shape); stepIndex();
        
      } else if (rotation == 2) {
        x1 = x0 + cos(radians(theta)) * unit;
        y1 = y0 + sin(radians(theta)) * unit;
        checkVertex(x1, y1);
        if (check == false) break;
        vertices[index] = new Vertex(x1, y1, shape); stepIndex();
        theta = theta + 60;
        
        x2 = x1 + cos(radians(theta)) * unit;
        y2 = y1 + sin(radians(theta)) * unit;
        checkVertex(x2, y2);
        if (check == false) break;
        vertices[index] = new Vertex(x2, y2, shape); stepIndex();
        theta = theta + 60;
        
        x3 = x2 + cos(radians(theta)) * unit;
        y3 = y2 + sin(radians(theta)) * unit;
        checkVertex(x3, y3);
        if (check == false) break;
        vertices[index] = new Vertex(x3, y3, shape); stepIndex();
        theta = theta + 120;
        
        x4 = x3 + cos(radians(theta)) * unit;
        y4 = y3 + sin(radians(theta)) * unit;
        checkVertex(x4, y4);
        if (check == false) break;
        vertices[index] = new Vertex(x4, y4, shape); stepIndex();
        
      } else if (rotation == 3) {
        x1 = x0 + cos(radians(theta)) * unit;
        y1 = y0 + sin(radians(theta)) * unit;
        checkVertex(x1, y1);
        if (check == false) break;
        vertices[index] = new Vertex(x1, y1, shape); stepIndex();
        theta = theta + 60;
        
        x2 = x1 + cos(radians(theta)) * unit;
        y2 = y1 + sin(radians(theta)) * unit;
        checkVertex(x2, y2);
        if (check == false) break;
        vertices[index] = new Vertex(x2, y2, shape); stepIndex();
        theta = theta + 120;
        
        x3 = x2 + cos(radians(theta)) * unit;
        y3 = y2 + sin(radians(theta)) * unit;
        checkVertex(x3, y3);
        if (check == false) break;
        vertices[index] = new Vertex(x3, y3, shape); stepIndex();
        
        x4 = x3 + cos(radians(theta)) * unit;
        y4 = y3 + sin(radians(theta)) * unit;
        checkVertex(x4, y4);
        if (check == false) break;
        vertices[index] = new Vertex(x4, y4, shape); stepIndex();
        
      } else if (rotation == 4){
        x1 = x0 + cos(radians(theta)) * unit;
        y1 = y0 + sin(radians(theta)) * unit;
        checkVertex(x1, y1);
        if (check == false) break;
        vertices[index] = new Vertex(x1, y1, shape); stepIndex();
        theta = theta + 120;
        
        x2 = x1 + cos(radians(theta)) * unit;
        y2 = y1 + sin(radians(theta)) * unit;
        checkVertex(x2, y2);
        if (check == false) break;
        vertices[index] = new Vertex(x2, y2, shape); stepIndex();
        
        x3 = x2 + cos(radians(theta)) * unit;
        y3 = y2 + sin(radians(theta)) * unit;
        checkVertex(x3, y3);
        if (check == false) break;
        vertices[index] = new Vertex(x3, y3, shape); stepIndex();
        theta = theta + 120;
        
        x4 = x3 + cos(radians(theta)) * unit;
        y4 = y3 + sin(radians(theta)) * unit;
        checkVertex(x4, y4);
        if (check == false) break;
        vertices[index] = new Vertex(x4, y4, shape); stepIndex();
        
      } else {
        x1 = x0 + cos(radians(theta)) * unit;
        y1 = y0 + sin(radians(theta)) * unit;
        checkVertex(x1, y1);
        if (check == false) break;
        vertices[index] = new Vertex(x1, y1, shape); stepIndex();
        
        x2 = x1 + cos(radians(theta)) * unit;
        y2 = y1 + sin(radians(theta)) * unit;
        checkVertex(x2, y2);
        if (check == false) break;
        vertices[index] = new Vertex(x2, y2, shape); stepIndex();
        theta = theta + 120;
        
        x3 = x2 + cos(radians(theta)) * unit;
        y3 = y2 + sin(radians(theta)) * unit;
        checkVertex(x3, y3);
        if (check == false) break;
        vertices[index] = new Vertex(x3, y3, shape); stepIndex();
        theta = theta + 60;
        
        x4 = x3 + cos(radians(theta)) * unit;
        y4 = y3 + sin(radians(theta)) * unit;
        checkVertex(x4, y4);
        if (check == false) break;
        vertices[index] = new Vertex(x4, y4, shape); stepIndex();
      }
      if (check == false) break;
    
      fill (255, 0, 0);
      beginShape();
      vertex(x0, y0);
      vertex(x1, y1);
      vertex(x2, y2);
      vertex(x3, y3);
      vertex(x4, y4);
      endShape(CLOSE);
      
      pickShape();
      
    } else if (shape == 4) { //blue large diamond (with 2 rotations)
      
      
      rotation = int(random(2));
    
      x1 = x0 + cos(radians(theta)) * unit;
      y1 = y0 + sin(radians(theta)) * unit;
      checkVertex(x1, y1);
      if (check == false) break;
      vertices[index] = new Vertex(x1, y1, shape); stepIndex();
      if (rotation == 1) {theta = theta + 120;}
      else {theta = theta + 60;}
      
      x2 = x1 + cos(radians(theta)) * unit;
      y2 = y1 + sin(radians(theta)) * unit;
      checkVertex(x2, y2);
      if (check == false) break;
      vertices[index] = new Vertex(x2, y2, shape); stepIndex();
      if (rotation == 1) {theta = theta + 60;}
      else {theta = theta + 120;}
      
      x3 = x2 + cos(radians(theta)) * unit;
      y3 = y2 + sin(radians(theta)) * unit;
      checkVertex(x3, y3);
      if (check == false) break;
      vertices[index] = new Vertex(x3, y3, shape); stepIndex();
      
    
      fill (0, 0, 255);
      beginShape();
      vertex(x0, y0);
      vertex(x1, y1);
      vertex(x2, y2);
      vertex(x3, y3);
      endShape(CLOSE);
      
      pickShape();
      
    } else if (shape == 5) { //gray small diamond (with 2 rotations)
      
      
      rotation = int(random(2));
    
      x1 = x0 + cos(radians(theta)) * unit;
      y1 = y0 + sin(radians(theta)) * unit;
      checkVertex(x1, y1);
      if (check == false) break;
      vertices[index] = new Vertex(x1, y1, shape); stepIndex();
      if (rotation == 1) {theta = theta + 150;}
      else {theta = theta + 30;}
      
      x2 = x1 + cos(radians(theta)) * unit;
      y2 = y1 + sin(radians(theta)) * unit;
      checkVertex(x2, y2);
      if (check == false) break;
      vertices[index] = new Vertex(x2, y2, shape); stepIndex();
      if (rotation == 1) {theta = theta + 30;}
      else {theta = theta + 150;}
      
      x3 = x2 + cos(radians(theta)) * unit;
      y3 = y2 + sin(radians(theta)) * unit;
      checkVertex(x3, y3);
      if (check == false) break;
      vertices[index] = new Vertex(x3, y3, shape); stepIndex();
      
    
      fill (127, 127, 127);
      beginShape();
      vertex(x0, y0);
      vertex(x1, y1);
      vertex(x2, y2);
      vertex(x3, y3);
      endShape(CLOSE);
      
      pickShape();
    }
    if (check == false) break;
  }
  
}




//function to pick shapes 0 through 5 randomly one at a time
void pickShape() {
  boolean allUsed = false;
  
  for (int j = 0; j < shapes.length; j++) {
    if (shapes[j]) {
      allUsed = true;
    } else {
      allUsed = false;
      j = shapes.length;
    } 
  }
  
  if (allUsed) {
    for (int i = 0; i < shapes.length; i++) {
      shapes[i] = false;
    }
  }
  
  shape = int(random(6));
  while (shapes[shape] == true) {
    shape = int(random(6));
  }
  shapes[shape] = true;
  
  vertices[index] = new Vertex(x0, y0, shape); stepIndex();
  
  check = false; //used to break out of drawShape
  
}

void stepIndex(){ // used after each time new vertix is recorded into array
  println(vertices[index].x + " " + vertices[index].y + " shape: " + vertices[index].shape);
  println("count: " + vertices[index].count);
  println("theta: " + theta0);
  println(" ");
  if (index < vertices.length-1) index++;
}

void checkVertex(float tempX, float tempY){ //tests for new proposed vertex
    
  if (vertices[index-1].count > 5) { //checks so there are not too many shapes at one vertex
    check = false;
  }
  
  for (int i = 0; i < index; i++) {
    if ((vertices[i].x == tempX) && (vertices[i].y == tempY)){
      if (vertices[i].shape == shape) { //checks so no duplicate shapes at same vertex       
        check = false; 
      }
    }
  }
  
  if (check == false) {
    index--;
    println ("     redo");
  }
  
}


class Vertex { 
  float x, y;
  int shape;
  int count;
  
  Vertex (float tempX, float tempY, int tempShape) {
    x = tempX;
    y = tempY;
    shape = tempShape; //records kind of shape at vertex
    
    count = 1; 
    for (int i = 0; i < index; i++) { //counts how many shapes share the vertex
      if ((vertices[i].x == x) && (vertices[i].y == y)) count++; 
    }
  }
  
  
  
}

Edit: I notice I’m also having some trouble with using ‘break’ and undoing the vertices proposed when they don’t pass the check (and how I used ‘index–’) .

I tried adding this code below to the check function and it seems to work some. I still have some problems with the array.

  color c0 = get(int(tempX), int(tempY));
  color c1 = get(int(tempX+1), int(tempY));
  color c2 = get(int(tempX-1), int(tempY));
  color c3 = get(int(tempX), int(tempY+1));
  color c4 = get(int(tempX), int(tempY-1));
  if ((c0 != #000000) && (c1 != #000000) && (c2 != #000000) && (c3 != #000000) && (c4 != #000000)) {
    check = false;
  }