Computer Science Canada

Paint Bucket

Author:  Andy [ Sat Mar 05, 2005 5:22 pm ]
Post subject:  Paint Bucket

many of you may have noticed that the turing drawfill command is very different than the paint bucket in ms paint.. a simple way to model this tool is to have a simple recursion that draws dots one by one.. but as we all know, that is very inefficient..
here is the source for the approach

Turing:

setscreen ("graphics:300;300,nobuttonbar")
drawstar (0, 0, 300, 300, blue)

var mx, my, mb : int

proc fill2 (x, y, clr, oclr : int)
    if x >= 0 and y >= 0 and x <= maxx and y <= maxy then
        drawdot (x, y, clr)
        for i : -1 .. 1
            for j : -1 .. 1
                if abs (i) not= abs (j) and whatdotcolor (x + i, y + j) = oclr then
                    fill2 (x + i, y + j, clr, oclr)
                end if
            end for
        end for
    end if
end fill2

proc fill (x, y, clr : int)
    if whatdotcolor (x, y) not= clr then
        setscreen ("offscreenonly")
        fill2 (x, y, clr, whatdotcolor (x, y))
        setscreen ("nooffscreenonly")
    end if
end fill

loop
    mousewhere (mx, my, mb)
    if mb = 1 then
        fill (mx, my, red)
    end if
end loop


a more efficient way to solve this problem is to simply trace the picture's boarder inside with the color you want to fill it with then use drawfill.. this however is slitely more complex

Turing:

setscreen ("graphics:300;300,nobuttonbar")
drawoval (150, 150, 149, 149, purple)
%drawbox (10, 10, 290, 290, blue)
%drawbox (10, 10, 100, 100, green)
%drawstar (10, 10, 290, 290, green)
var mx, my, mb : int

forward proc search (x, y, nclr, oclr, a, b : int)

proc draw (x, y, nclr, oclr : int)
    if whatdotcolor (x, y) = oclr then
        if whatdotcolor (x + 1, y) not= nclr and whatdotcolor (x + 1, y) not= oclr then
            search (x, y + 1, nclr, oclr, 1, 0)
            drawdot (x, y, nclr)
            search (x, y - 1, nclr, oclr, 1, 0)
            if whatdotcolor (x - 1, y) = oclr then
                search (x - 1, y + 1, nclr, oclr, 1, 0)
                search (x - 1, y - 1, nclr, oclr, 1, 0)
            end if
            if whatdotcolor (x, y + 1) = oclr then
                search (x + 1, y + 1, nclr, oclr, 0, -1)
            elsif whatdotcolor (x, y - 1) = oclr then
                search (x + 1, y - 1, nclr, oclr, 0, 1)
            end if
        end if
        if whatdotcolor (x, y + 1) not= nclr and whatdotcolor (x, y + 1) not= oclr then
            search (x - 1, y, nclr, oclr, 0, 1)
            drawdot (x, y, nclr)
            search (x + 1, y, nclr, oclr, 0, 1)
            if whatdotcolor (x, y - 1) = oclr then
                search (x - 1, y - 1, nclr, oclr, 0, 1)
                search (x + 1, y - 1, nclr, oclr, 0, 1)
            end if
            if whatdotcolor (x + 1, y) = oclr then
                search (x + 1, y + 1, nclr, oclr, -1, 0)
            elsif whatdotcolor (x - 1, y) = oclr then
                search (x - 1, y + 1, nclr, oclr, 1, 0)
            end if
        end if
        if whatdotcolor (x - 1, y) not= nclr and whatdotcolor (x - 1, y) not= oclr then
            search (x, y - 1, nclr, oclr, -1, 0)
            drawdot (x, y, nclr)
            search (x, y + 1, nclr, oclr, -1, 0)
            if whatdotcolor (x + 1, y) = oclr then
                search (x + 1, y + 1, nclr, oclr, -1, 0)
                search (x + 1, y - 1, nclr, oclr, -1, 0)
            end if
            if whatdotcolor (x, y + 1) = oclr then
                search (x - 1, y + 1, nclr, oclr, 0, -1)
            elsif whatdotcolor (x, y - 1) = oclr then
                search (x - 1, y - 1, nclr, oclr, 0, 1)
            end if
        end if
        if whatdotcolor (x, y - 1) not= nclr and whatdotcolor (x, y - 1) not= oclr then
            search (x + 1, y, nclr, oclr, 0, -1)
            drawdot (x, y, nclr)
            search (x - 1, y, nclr, oclr, 0, -1)
            if whatdotcolor (x, y + 1) = oclr then
                search (x - 1, y + 1, nclr, oclr, 0, -1)
                search (x + 1, y + 1, nclr, oclr, 0, -1)
            end if
            if whatdotcolor (x + 1, y) = oclr then
                search (x + 1, y - 1, nclr, oclr, -1, 0)
            elsif whatdotcolor (x - 1, y) = oclr then
                search (x - 1, y - 1, nclr, oclr, 1, 0)
            end if
        end if
    end if

end draw

body proc search (x, y, nclr, oclr, a, b : int)
    if whatdotcolor (x, y) = oclr and x >= 0 and y >= 0 and x <= maxx and y <= maxy then
        if whatdotcolor (x + a, y + b) = whatdotcolor (x, y) then
            search (x + a, y + b, nclr, oclr, a, b)
        else
            draw (x, y, nclr, oclr)
        end if
    end if
end search

proc fill (x, y, clr : int)
    if whatdotcolor (x, y) not= clr then
        search (x, y, clr, whatdotcolor (mx, my), 1, 0)
        search (x, y, clr, whatdotcolor (mx, my), -1, 0)
        search (x, y, clr, whatdotcolor (mx, my), 0, 1)
        search (x, y, clr, whatdotcolor (mx, my), 0, -1)
        drawfill (x, y, red, red)
    end if
end fill

loop
    mousewhere (mx, my, mb)
    if mb = 1 then
        fill (mx, my, red)
        delay (10)
    end if
end loop

if you guys have any problems feel free to post here.

Author:  Andy [ Sun Mar 06, 2005 6:51 pm ]
Post subject: 

o and uncomment different combinations of shapes at the top of the program to test it out.. currently i am aware of a glitch that misses some pixels because by tracing out the shape, you sometimes isolate pixels which are ignored when drawfill is activated... i'll try to come up with a solution to that problem either late nxt week or early the week after

Author:  ssr [ Sun Mar 06, 2005 7:58 pm ]
Post subject: 

is it me?
but I dont think ur second code is working properly
but all teh shapes down adn drawfill it Question

Author:  Andy [ Mon Mar 07, 2005 7:50 am ]
Post subject: 

thx for trying it out for me.. yea i see now what the bug is... and its gona take a while to fix lol

Author:  ssr [ Mon Mar 07, 2005 7:10 pm ]
Post subject: 

Andy wrote:
thx for trying it out for me.. yea i see now what the bug is... and its gona take a while to fix lol

np
tnx for the code btw

Author:  person [ Tue Mar 08, 2005 3:42 pm ]
Post subject: 

can u please comment the code???? i really dont get it

Author:  Andy [ Tue Mar 08, 2005 5:03 pm ]
Post subject: 

if you dont get it then commenting wont really help.. trust me, its just simple recursion

Author:  mike200015 [ Tue Mar 08, 2005 8:44 pm ]
Post subject: 

whats the difference between the first and the second programs tho, and whats the advantage of using the second one over the first one?

Author:  McKenzie [ Tue Mar 08, 2005 9:31 pm ]
Post subject: 

What Andy is saying is that the drawfill from Holt is optimized (odds are it is a straight C port) but it has the limitation of only being able to fill in a shape that is outlined by all the same colour. What he is trying to do is trace the inside of the shape then use drawfill for it's speed.

Author:  Andy [ Wed Mar 09, 2005 4:03 pm ]
Post subject: 

run both codes and you'll see that the first one is much much slower... the second one was written with the concept of efficiency in mind

Author:  mike200015 [ Wed Mar 09, 2005 8:54 pm ]
Post subject: 

Surprised Idea kk got it

Author:  Dude_man_47 [ Fri Dec 01, 2006 6:55 pm ]
Post subject: 

I also noticed that if you uncomment the rest of the shapes and try to fill in the center of the star you get a stack overflow. Hopefully this gets fixed.


: