extrapixel
Full Member
Offline
Posts: 210
Switzerland
Re: Color fill / Paint bucket effect
Reply #1 - Dec 30th , 2007, 2:41am
do you mean flood-fill? (seen here: http://processing.org/discourse/yabb/YaBB.cgi?board=Syntax;action=display;num=1112372959 ) // MIKKEL CRONE KOSER // BEYONDTHREE.COM // FLOOD_FILL SKETCH *array-style // APRIL 2005 void setup(){ size(1400, 900, P3D); background(255); noFill(); drawRandomBoxes(); } void draw(){ } void mousePressed(){ floodFill(mouseX, mouseY, color((int)random(100, 200), (int)random(100, 200), 0)); } // ******* FLOOD FILL ********* // original by Mark Wutka ( http://docs.rinet.ru/UJ11/ch31.htm ) // modified for processing by Mikkel Crone Koser ( www.beyondthree.com ) // modified syntax to work with Processing 0125 Beta by extrapixel.ch // // floodFill starts at a particular x and y coordinate and fills it, and all // the surrounding pixels with a color. It doesn't paint over black pixels, // so they represent the borders of the fill. // The easiest way to code a flood fill is by doing it recursively - you // call flood fill on a pixel, color that pixel, then it calls flood fill // on each surrounding pixel and so on. Unfortunately, that usually causes // stack overflows since recursion is pretty expensive. // This routine uses an alternate method. It makes a queue of pixels that // it still has to fill. It takes a pixel off the head of the queue and // colors the pixels around it, then adds those pixels to the queue. In other // words, a pixel is really added to the queue after it has been colored. // If a pixel has already been colored, it is not added, so eventually, it // works the queue down until it is empty. public void floodFill(int x, int y, int col) { // If the pixel we are starting with is already black, we won't paint if (get(x, y) == (int)color(0,0,0)){ return; } // Create the pixel queue. Assume the worst case where every pixel in the // image may be in the queue. int pixelQueue[] = new int[width * height]; int pixelQueueSize = 0; // Add the start pixel to the queue (we created a single array of ints, // even though we are enqueuing two numbers. We put the y value in the // upper 16 bits of the integer, and the x in the lower 16. This gives // a limit of 65536x65536 pixels, that should be enough.) pixelQueue[0] = (y << 16) + x; pixelQueueSize = 1; // Color the start pixel. set(x, y, col); // Keep going while there are pixels in the queue. while (pixelQueueSize > 0){ // Get the x and y values of the next pixel in the queue x = pixelQueue[0] & 0xffff; y = (pixelQueue[0] >> 16) & 0xffff; // Remove the first pixel from the queue. Rather than move all the // pixels in the queue, which would take forever, just take the one // off the end and move it to the beginning (order doesn't matter here). pixelQueueSize--; pixelQueue[0] = pixelQueue[pixelQueueSize]; // If we aren't on the left side of the image, see if the pixel to the // left has been painted. If not, paint it and add it to the queue. if (x > 0) { if ((get(x-1, y) != (int)color(0,0,0)) && (get(x-1, y) != col)) { set(x-1, y, col); pixelQueue[pixelQueueSize] = (y << 16) + x-1; pixelQueueSize++; } } // If we aren't on the top of the image, see if the pixel above // this one has been painted. If not, paint it and add it to the queue. if (y > 0) { if ((get(x, y-1) != (int)color(0,0,0)) && (get(x, y-1) != col)) { set(x, y-1, col); pixelQueue[pixelQueueSize] = ((y-1) << 16) + x; pixelQueueSize++; } } // If we aren't on the right side of the image, see if the pixel to the // right has been painted. If not, paint it and add it to the queue. if (x < width-1) { if ((get(x+1, y) != (int)color(0,0,0)) && (get(x+1, y) != col)) { set(x+1, y, col); pixelQueue[pixelQueueSize] = (y << 16) + x+1; pixelQueueSize++; } } // If we aren't on the bottom of the image, see if the pixel below // this one has been painted. If not, paint it and add it to the queue. if (y < height-1) { if ((get(x, y+1) != (int)color(0,0,0)) && (get(x, y+1) != col)) { set(x, y+1, col); pixelQueue[pixelQueueSize] = ((y+1) << 16) + x; pixelQueueSize++; } } } updatePixels(); } void drawRandomBoxes(){ for(int i=0; i<30; i++){ int x = (int)random(0, width); int y = (int)random(0, height); int w = (int)random(40, 400); int h = (int)random(40, 400); pushMatrix(); // rotateZ(random(PI)); rect(x, y, w, h); popMatrix(); } }