I am attempting to program the visualizations from this video. Essentially, it is a problem of propagating a signal through a graph. In this case, the graph is the canvas, the vertices are the pixels, the links exist between neighboring pixels (so each pixel has at most 4 links), and the signal is their color. Until the canvas isn’t fully colored, I pick an uncolored pixel and begin propagating the data by visiting the neighbors of this pixel that I haven’t visited yet. I store the pixels that have already been visited, but which still contain unvisited neighbors, in a stack data structure, and when its size reaches 0, that tells me the given room has been fully flooded, so then I move onto the next room (if there is one). The video also talks about a parameter that determines the probability with which each link is initialized as “open” vs “closed”. To me, the most interesting case is when the probability is 50%, which is why I’ve decided to hard-code this in - the probability is chosen with (int)random(2)
, and the result represents the 50/50 case.
Now then, below is my code, and my question is, is there any way to optimize it further? It’s already pretty fast, as I tried my best to make it efficient. Also, one small thing that I did not anticipate is how much memory it uses - I have to allocate gigabytes of RAM for canvas sizes above 1000×1000, and I do not know why that is; is it normal for this kind of program?
int colors = 256 * 256 * 256, offset;
PGraphics pg;
class Cell {
int group = -1, id, x, y;
int[][] next;
boolean dirCond[];
color c;
Cell(int id) {
this.id = id;
this.x = id % pg.width;
this.y = id / pg.width;
next = new int[][]{
{id - pg.width, (int)random(2)},
{id - 1, (int)random(2)},
{id + 1, (int)random(2)},
{id + pg.width, (int)random(2)}
};
if (x > 0) next[1][1] = cells[id - 1].next[2][1];
if (y > 0) next[0][1] = cells[id - pg.width].next[3][1];
dirCond = new boolean[]{y > 0, x > 0, x < pg.width - 1, y < pg.height - 1};
}
}
Cell[] cells;
void setup() {
pg = createGraphics(600, 600);
cells = new Cell[pg.width * pg.height];
offset = (int)random(colors);
for (int i = 0; i < cells.length; i++)
cells[i] = new Cell(i);
int[] stack = new int[cells.length];
for (int id = 0, g = 0; id != -1; g++, id = getNext(id)) {
int rand = (int)random(colors);
color c = color(rand % 256, rand / 256 % 256, rand / 256 / 256);
cells[stack[0] = id].group = g;
for (int ptr = 0; ptr != -1; ptr--) {
Cell cell = cells[stack[ptr]];
cell.c = c;
for (int i = 0; i < 4; i++) {
int next = cell.next[i][0];
if (cell.dirCond[i] && cells[next].group == -1 && cell.next[i][1] < 1)
cells[stack[ptr++] = next].group = cell.group;
}
}
}
pg.beginDraw();
for (Cell cell : cells) {
pg.stroke(cell.group == -1 ? 255 : cell.c);
pg.point(cell.x, cell.y);
}
pg.endDraw();
pg.save("image.png");
exit();
}
int getNext(int prev) {
for (int i = prev + 1; i < cells.length; i++) {
if (cells[i].group == -1)
return i;
}
return -1;
}