Results 1 to 9 of 9

Thread: Fill [RESOLVED]

  1. #1

    Thread Starter
    Fanatic Member Nove's Avatar
    Join Date
    Jul 2004
    Posts
    736

    Resolved Fill [RESOLVED]

    I'm working on a function to work as a fill, this is for a tile editor but it has the same principles you would use when working with a bitmap. The only solution for creating a fill function that comes to mind is to start at an initial point and from within in the function check and see if the current tile matches up with any corresponding tiles, then once the change has been made, call itself with a new x,y point. This would work great, except I run out of stack space real quick. Does anyone have a workaround for this? Thanks.
    Last edited by Nove; Nov 8th, 2005 at 07:48 PM.

  2. #2
    PowerPoster Fox's Avatar
    Join Date
    Jan 2000
    Location
    *afk*
    Posts
    2,088

    Re: Fill

    You can get around any stack problem by putting the data into a seperate list (because you can step through the list in a loop, thus not needing a recursive function).

  3. #3
    type Woss is new Grumpy; wossname's Avatar
    Join Date
    Aug 2002
    Location
    #!/bin/bash
    Posts
    5,682

    Re: Fill

    How many tiles are we talking about? Call stack overflow normally only occurs with ENORMOUS amounts of data or an unterminated recursive function.
    I don't live here any more.

  4. #4

    Thread Starter
    Fanatic Member Nove's Avatar
    Join Date
    Jul 2004
    Posts
    736

    Re: Fill

    Well, the space was 200x200 and it stopped somewhere around 72,31. It's somewhat of a balloon movement so I don't know how many calls of the function were running at that moment.
    Fox, what are you proposing? I don't think I understand.

  5. #5
    PowerPoster Fox's Avatar
    Join Date
    Jan 2000
    Location
    *afk*
    Posts
    2,088

    Re: Fill

    Pseudo code:

    VB Code:
    1. Sub FloodFill( StartX, Start )
    2.     CreateTodoList() 'Empty list that holds the items we have to check
    3.     CreateDoneMap( Width, Height ) 'Bool map storing already processed positions
    4.  
    5.     TodoList.Add( StartX, StartY ) 'Adds first item to list
    6.  
    7.     While( TodoList.Count > 0 ) 'While there is something to do...
    8.         Position = TodoList.RemoveFirst() 'Remove one item (get x and y)
    9.         DoneMap( Pos ) = True 'Mark current position as done
    10.  
    11.         If FreeTile( x, y ) Then 'If current position is free
    12.             FillTile( x, y ) 'Process that tile, eg. fill it
    13.  
    14.             'Add neighbours if they were not already checked
    15.             If Not DoneMap( x, y-1 ) Then: TodoList.Add( x, y-1 )
    16.             If Not DoneMap( x+1, y ) Then: TodoList.Add( x+1, y )
    17.             If Not DoneMap( x, y+1 ) Then: TodoList.Add( x, y+1 )
    18.             If Not DoneMap( x-1, y ) Then: TodoList.Add( x-1, y )
    19.         Endif
    20.     Wend
    21. End Sub

    Have fun.
    Last edited by Fox; Nov 8th, 2005 at 07:31 PM. Reason: Speedfix

  6. #6
    PowerPoster Fox's Avatar
    Join Date
    Jan 2000
    Location
    *afk*
    Posts
    2,088

    Re: Fill

    I just felt like writing some sample code out of this ^^'

    Code:
    Public Sub FloodFill(DC As Long, x As Long, y As Long, w As Long, h As Long, Color As Long)
        Dim StartColor As Long
        
        Dim TodoList As New Collection
        Dim DoneMap() As Boolean
        
        Dim TempPos As cPos2D
        Dim NewPos As cPos2D
        
        ReDim DoneMap(w, h)
        StartColor = GetPixel(DC, x, y)
        
        Set TempPos = New cPos2D
        TempPos.x = x
        TempPos.y = y
        TodoList.Add TempPos
        DoneMap(x, y) = True
        
        While TodoList.Count > 0
            Set TempPos = TodoList.Item(1)
            TodoList.Remove 1
            
            If GetPixel(DC, TempPos.x, TempPos.y) = StartColor Then
                SetPixelV DC, TempPos.x, TempPos.y, Color
                
                Set NewPos = New cPos2D
                NewPos.x = TempPos.x: NewPos.y = TempPos.y - 1
                If NewPos.y > -1 Then
                    If Not DoneMap(NewPos.x, NewPos.y) Then
                        TodoList.Add NewPos
                        DoneMap(NewPos.x, NewPos.y) = True
                    End If
                End If
                
                Set NewPos = New cPos2D
                NewPos.x = TempPos.x: NewPos.y = TempPos.y + 1
                If NewPos.y < h Then
                    If Not DoneMap(NewPos.x, NewPos.y) Then
                        TodoList.Add NewPos
                        DoneMap(NewPos.x, NewPos.y) = True
                    End If
                End If
                
                Set NewPos = New cPos2D
                NewPos.x = TempPos.x - 1: NewPos.y = TempPos.y
                If NewPos.x > -1 Then
                    If Not DoneMap(NewPos.x, NewPos.y) Then
                        TodoList.Add NewPos
                        DoneMap(NewPos.x, NewPos.y) = True
                    End If
                End If
                
                Set NewPos = New cPos2D
                NewPos.x = TempPos.x + 1: NewPos.y = TempPos.y
                If NewPos.x < w Then
                    If Not DoneMap(NewPos.x, NewPos.y) Then
                        TodoList.Add NewPos
                        DoneMap(NewPos.x, NewPos.y) = True
                    End If
                End If
            End If
        Wend
    End Sub
    Usage:

    VB Code:
    1. FloodFill Picture1.hdc, 10, 10, Picture1.ScaleWidth, Picture1.ScaleHeight, RGB(255, 0, 255)

    To make life easier I used the Collection class, unfortunately it only accepts objects so you have to add a new object module to the project, name it cPos2D and add the following lines to it:

    VB Code:
    1. Public x As Long
    2.     Public y As Long

    And don't forget the API declares in the module of your choide:

    Code:
        Public Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
        Public Declare Function SetPixelV Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal crColor As Long) As Long
    Yeah it's dumb but it shows that the code works

    [edit] Speedfixes... [/edit]
    Last edited by Fox; Nov 8th, 2005 at 07:24 PM.

  7. #7

    Thread Starter
    Fanatic Member Nove's Avatar
    Join Date
    Jul 2004
    Posts
    736

    Re: Fill

    Ok, I see now, incredibly helpful, thank you very much. Thanks for all the help thus far

  8. #8
    PowerPoster Fox's Avatar
    Join Date
    Jan 2000
    Location
    *afk*
    Posts
    2,088

    Re: Fill [RESOLVED]

    If you're going to implement the technique please pay attention to the example code. But as long as you got the point it's up to you to keep it stable and optimized (eg. the <0,<0 and >w,>h checks are absolutely necessary)

  9. #9

    Thread Starter
    Fanatic Member Nove's Avatar
    Join Date
    Jul 2004
    Posts
    736

    Re: Fill [RESOLVED]

    Yes, I probably won't implement the code directly, but you got your point across. Thank you very much.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width