buggy flood fill

This commit is contained in:
visionmercer 2026-05-01 13:58:36 +02:00
commit 218e54ce70
2 changed files with 120 additions and 7 deletions

View file

@ -1,6 +1,6 @@
sub filledPolygon (Points() as single, col as long) sub filledPolygon (Points() as long, col as long)
dim i as integer, j as integer dim i as integer, j as integer
dim x1 as single, y1 as single, x2 as single, y2 as single dim x1 as single, y1 as single, x2 as single, y2 as single
dim intersectX as single dim intersectX as single
@ -67,8 +67,9 @@ Sub polygon (pa() As Long,col as long)
For i = 2 To UBound(pa) Step 2 For i = 2 To UBound(pa) Step 2
thickLine pa(i - 2), pa(i - 1),pa(i), pa(i + 1),col thickLine pa(i - 2), pa(i - 1),pa(i), pa(i + 1),col
Next i Next i
thickLine pa(i - 1), pa(i - 2),pa(0), pa(1),col thickLine pa(ubound(pa)-1), pa(ubound(pa)),pa(0), pa(1),col
End Sub End Sub
sub thickcircle(x, y, r, col as long) sub thickcircle(x, y, r, col as long)
if state.brushsize <= 1 then if state.brushsize <= 1 then
circle (x, y), r, col circle (x, y), r, col
@ -143,3 +144,100 @@ sub filledcircle(x,y,r,col as long)
line (x-tx,y+ty)-(x+tx,y+ty),col line (x-tx,y+ty)-(x+tx,y+ty),col
wend wend
end sub end sub
sub floodfill (x as integer, y as integer, fillcolor as long)
dim as integer leftx, rightx, currenty
dim as integer arrsize, stackptr
' Create a stack for storing coordinates
arrsize = 1000 ' Adjust based on expected complexity
redim stack(1 to arrsize, 1 to 2) as integer
stackptr = 0
' Get the color at starting point
dim startcolor as long
startcolor = point(x, y)
' If starting on boundary color or fill color, exit
if startcolor = fillcolor then exit sub
' Push starting point to stack
stackptr = stackptr + 1
stack(stackptr, 1) = x
stack(stackptr, 2) = y
' Process until stack is empty
do while stackptr > 0
' Pop a point from stack
x = stack(stackptr, 1)
y = stack(stackptr, 2)
stackptr = stackptr - 1
' Skip if current point is not startcolor
if point(x, y) <> startcolor then _continue
' Find leftmost point on this scanline
leftx = x
do while leftx > 0 and point(leftx - 1, y) = startcolor
leftx = leftx - 1
loop
' Find rightmost point on this scanline
rightx = x
do while rightx < _width - 1 and point(rightx + 1, y) = startcolor
rightx = rightx + 1
loop
' Fill the scanline
line (leftx, y)-(rightx, y), fillcolor
' Check scanline above
currenty = y - 1
if currenty >= 0 then
for x = leftx to rightx
if point(x, currenty) = startcolor then
' Push seed point to stack
stackptr = stackptr + 1
if stackptr > arrsize then
' Resize stack if needed
arrsize = arrsize * 2
redim _preserve stack(1 to arrsize, 1 to 2) as integer
end if
stack(stackptr, 1) = x
stack(stackptr, 2) = currenty
' Skip adjacent pixels of same color
do while x <= rightx and point(x, currenty) = startcolor
x = x + 1
loop
x = x - 1 ' Adjust for loop increment
end if
next x
end if
' Check scanline below
currenty = y + 1
if currenty < _height then
for x = leftx to rightx
if point(x, currenty) = startcolor then
' Push seed point to stack
stackptr = stackptr + 1
if stackptr > arrsize then
' Resize stack if needed
arrsize = arrsize * 2
redim _preserve stack(1 to arrsize, 1 to 2) as integer
end if
stack(stackptr, 1) = x
stack(stackptr, 2) = currenty
' Skip adjacent pixels of same color
do while x <= rightx and point(x, currenty) = startcolor
x = x + 1
loop
x = x - 1 ' Adjust for loop increment
end if
next x
end if
loop
end sub

View file

@ -179,6 +179,17 @@ sub canvas
' 4. Interaction Logic ' 4. Interaction Logic
if _mousex > boxX1 then if _mousex > boxX1 then
' Start Drawing Logic ' Start Drawing Logic
if state.tool = 9 and (mouseclicked or rmouseclicked) then
_dest layers(2).ihandle
_source layers(2).ihandle
if mouseclicked then
floodfill canX,canY,state.fcolor
else
floodfill canX,canY,state.bcolor
end if
_dest 0
_source 0
end if
if state.tool = 7 or state.tool = 8 then if state.tool = 7 or state.tool = 8 then
if mouseclicked then if mouseclicked then
polypoints(pointCount * 2) = canX polypoints(pointCount * 2) = canX
@ -238,16 +249,15 @@ sub canvas
if commit then if commit then
_dest layers(1).ihandle ' Final destination is always the drawing layer _dest layers(1).ihandle ' Final destination is always the drawing layer
if state.tool = 8 and pointCount > 2 then if (state.tool = 8 or state.tool=7) and pointCount > 2 then
redim finalP(pointCount * 2 - 1) as single redim finalP(pointCount * 2 - 1) as long
for p = 0 to (pointCount * 2) - 1: finalP(p) = polypoints(p): next for p = 0 to (pointCount * 2) - 1: finalP(p) = polypoints(p): next
filledPolygon finalP(), drawCol ' Using tools.bm sub[cite: 2] if state.tool =8 then filledPolygon finalP(), drawCol else Polygon finalP(), drawCol
else else
' Merge the preview into the drawing layer[cite: 1] ' Merge the preview into the drawing layer
_putimage , layers(2).ihandle, layers(1).ihandle _putimage , layers(2).ihandle, layers(1).ihandle
end if end if
' Clear preview layer[cite: 1]
_dest layers(2).ihandle: cls , 0 _dest layers(2).ihandle: cls , 0
state.isDrawing = 0 state.isDrawing = 0
pointCount = 0 pointCount = 0
@ -275,6 +285,11 @@ function icon (index as long)
' Draw a small filled shape for the filled polygon icon ' Draw a small filled shape for the filled polygon icon
for fy = 10 to 20: line (10, fy)-(22, fy): next for fy = 10 to 20: line (10, fy)-(22, fy): next
_dest 0 _dest 0
icons(8) = _newimage(32, 32, 32): _dest icons(8)
' Simple "Bucket" icon
line (8, 10)-(24, 10): line -(26, 22): line -(6, 22): line -(8, 10)
line (10, 8)-(22, 8) ' Handle
_dest 0
' Fill the remaining slots with blank 32x32 images ' Fill the remaining slots with blank 32x32 images
dim j as integer dim j as integer
for j = 0 to 19 for j = 0 to 19