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–’) .