Hey
I am pretty new to processing and jumped right in.
The sketch I am currently learning with has a continuos line being drawn accross the canvas. To whatever point line is drawn to, I want to originate a flood fill of a random color from. After some trying around I got the flood fill working following this "rough" algorithm:
Somehow my functions is very ineffective though, as with growing canvas size the flood fill takes longer and longer to complete, steming from a ever growing size of my queue. I was wondering if someone has suggestions on how to optimize my code or explain to me how to avoid this type of problem.
I suppose you'll have better understanding, if I share the whole sketch so you can try for youself, but the while-loop in the floodFill function obvisouly is my point of concern. The 200x200 canvas in the code is barely running, just lifting the size to 300x300 almost times out completely.
Cheers,
k.
I am pretty new to processing and jumped right in.
The sketch I am currently learning with has a continuos line being drawn accross the canvas. To whatever point line is drawn to, I want to originate a flood fill of a random color from. After some trying around I got the flood fill working following this "rough" algorithm:
1 Have a way to mark visited points
2 At the beginning, queue the start point.
3 While the queue is not empty, continue dequeuing its element. And with each element
1 Fill its color and mark just-dequeued point as visited
2 Enqueue unvisited adjacent points that has the same color
Somehow my functions is very ineffective though, as with growing canvas size the flood fill takes longer and longer to complete, steming from a ever growing size of my queue. I was wondering if someone has suggestions on how to optimize my code or explain to me how to avoid this type of problem.
I suppose you'll have better understanding, if I share the whole sketch so you can try for youself, but the while-loop in the floodFill function obvisouly is my point of concern. The 200x200 canvas in the code is barely running, just lifting the size to 300x300 almost times out completely.
- float x = 0;
float y = 0;
int padding = 3;
color strokeColor = color(255);
void setup()
{
frameRate(2);
size(200, 200);
background(0);
}
void draw()
{
// draw the line
float oldX = x;
float oldY = y;
x = random(0, width);
y = random(0, height);
stroke(strokeColor);
line(oldX, oldY, x, y);
// fill from where the line pointed to
floodFill(x, y, randomColor());
// call it quits after 30 frames
if (frameCount > 30) {
noLoop();
}
}
/*
* fill the canvas starting from startX, startY
*/
void floodFill(float startX, float startY, color startColor)
{
int [][] imgPoints = new int[width][height];
for (int c = 0; c < imgPoints.length; c++) {
for (int r = 0; r < imgPoints[0].length; r++) {
imgPoints[c][r] = 0;
}
}
int [] queuedX = new int[0];
int [] queuedY = new int[0];
queuedX = append(queuedX, int(startX));
queuedY = append(queuedY, int(startY));
while (queuedX.length > 0) {
println("queue length: " + queuedX.length);
int currentX = queuedX[queuedX.length -1];
int currentY = queuedY[queuedY.length - 1];
// fill this point
if (get(currentX, currentY) != strokeColor) {
stroke(startColor);
point(currentX, currentY);
}
// mark current point in queue as visited
queuedX = shorten(queuedX);
queuedY = shorten(queuedY);
imgPoints[currentX][currentY] = 1;
// check adjancent points within bounds
if ( currentX > padding
&& currentX < width - padding
&& currentY > padding
&& currentY < height - padding
){
// add whatever points are not checked yet && need coloring
// left
if (imgPoints[currentX - 1][currentY] == 0 && get(currentX - 1, currentY) != strokeColor) {
queuedX = append(queuedX, currentX - 1);
queuedY = append(queuedY, currentY);
imgPoints[currentX - 1][currentY] = 1;
}
// right
if (imgPoints[currentX + 1][currentY] == 0 && get(currentX + 1, currentY) != strokeColor) {
queuedX = append(queuedX, currentX + 1);
queuedY = append(queuedY, currentY);
imgPoints[currentX + 1][currentY] = 1;
}
// bottom
if (imgPoints[currentX][currentY - 1] == 0 && get(currentX, currentY - 1) != strokeColor) {
queuedX = append(queuedX, currentX);
queuedY = append(queuedY, currentY - 1);
imgPoints[currentX][currentY - 1] = 1;
}
// top
if (imgPoints[currentX][currentY + 1] == 0 && get(currentX, currentY + 1) != strokeColor) {
queuedX = append(queuedX, currentX);
queuedY = append(queuedY, currentY + 1);
imgPoints[currentX][currentY + 1] = 1;
}
}
// escape
if (queuedX.length > 200000) {
println("exit, too much in queue");
queuedX = new int[0];
noLoop();
}
} // end while
} // end floodFill()
/*
* return a random color
*/
color randomColor()
{
float r = random(0, 255);
float g = random(0, 255);
float b = random(0, 255);
return color(r, g, b);
//return color(255, 0, 0);
}
Cheers,
k.
1