Re: PAINT in Basic...
Here's two versions of painting procedures that I use:
Paint is like the basic statement
Fill is like in picture editing programs
--- code begins
procedure paint(object tile, sequence p, integer targ)
-- replaces all pixels bounded by targ colored pixels starting at some
point p
-- tile may be an atom for a solid color
-- or a 2-d sequence of pixels to be tiled
-- warning: this procedure is not aware of screen boundaries - be sure
that
-- the object to be painted has a closed border
sequence stack, testp, scan
integer index, ok
stack = {{p, 0}}
index = 1
while index <= length(stack) do
p = stack[index][1]
-- scoot all the way to the left
while get_pixel(p-{1,0}) != targ do
p[1] = p[1] - 1
end while
stack[index][1] = p
-- set flags
scan = {0,0}
-- scan across current line of target color
while get_pixel(p) != targ do
-- look for target color above/below current pixel
for z = 1 to 2 do
testp = p - {0, 3 - 2 * z}
if (get_pixel(testp) != targ) then
if scan[z] = 0 then
-- start of above/below strip
ok = 1
for i = 1 to length(stack) do
if stack[i][1][2] = testp[2] then
if testp[1] >= stack[i][1][1]
and testp[1] < stack[i][1][1] + stack[i][2]
then
-- this strip has already been scanned
ok = 0
exit
end if
end if
end for
if ok then
-- remember it for later
stack = append(stack, {testp, 1})
end if
scan[z] = 1
end if
elsif scan[z] = 1 then
-- end of above/below strip
scan[z] = 0
end if
end for
p[1] = p[1] + 1
end while
stack[index][2] = p[1] - stack[index][1][1]
index = index + 1
end while
if atom(tile) then
-- pixels
for i = 1 to length(stack) do
pixel(repeat(tile, stack[i][2]), stack[i][1])
end for
else
-- tile image
for i = 1 to length(stack) do
for x = stack[i][1][1] to stack[i][1][1] + stack[i][2] - 1
do
pixel(tile[1+remainder(stack[i][1][2],
length(tile))][1+remainder(x, length(tile[1]))], {x,stack[i][1][2]})
end for
end for
end if
end procedure
procedure fill(object tile, sequence p, integer targ)
-- replaces all occurences of targ colored adjacent pixels starting at
some point p
-- tile may be an atom for a solid color
-- or a 2-d sequence of pixels to be tiled
sequence stack, testp, scan
integer index, ok
stack = {{p, 0}}
index = 1
while index <= length(stack) do
p = stack[index][1]
-- scoot all the way to the left
while get_pixel(p-{1,0}) = targ do
p[1] = p[1] - 1
end while
stack[index][1] = p
-- set flags
scan = {0,0}
-- scan across current line of target color
while get_pixel(p) = targ do
-- look for target color above/below current pixel
for z = 1 to 2 do
testp = p - {0, 3 - 2 * z}
if (get_pixel(testp) = targ) then
if scan[z] = 0 then
-- start of above/below strip
ok = 1
for i = 1 to length(stack) do
if stack[i][1][2] = testp[2] then
if testp[1] >= stack[i][1][1]
and testp[1] < stack[i][1][1] + stack[i][2]
then
-- this strip has already been scanned
ok = 0
exit
end if
end if
end for
if ok then
-- remember it for later
stack = append(stack, {testp, 1})
end if
scan[z] = 1
end if
elsif scan[z] = 1 then
-- end of above/below strip
scan[z] = 0
end if
end for
p[1] = p[1] + 1
end while
stack[index][2] = p[1] - stack[index][1][1]
index = index + 1
end while
if atom(tile) then
-- pixels
for i = 1 to length(stack) do
pixel(repeat(tile, stack[i][2]), stack[i][1])
end for
else
-- tile image
for i = 1 to length(stack) do
for x = stack[i][1][1] to stack[i][1][1] + stack[i][2] - 1
do
pixel(tile[1+remainder(stack[i][1][2],
length(tile))][1+remainder(x, length(tile[1]))], {x,stack[i][1][2]})
end for
end for
end if
end procedure
-- demonstration code
include graphics.e
if graphics_mode(19) then
end if
ellipse(5, 1, {10,10},{50,50})
ellipse(5, 1, {50,10},{190,50})
ellipse(5, 1, {10,50},{50,190})
ellipse(6, 1, {50,50},{190,190})
-- yellow '/' on green fill
fill({{2,2,14},{2,14,2},{14,2,2}}, {35,35}, 5)
-- white '\' on blue paint
paint({{15,1,1,1},{1,15,1,1},{1,1,15,1},{1,1,1,15}}, {35,35}, 0)
--- code ends ---
Enjoy!
Pete Eberlein <xseal at harborside.com>
|
Not Categorized, Please Help
|
|