Skip to content

EliahKagan/Flood

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Flood - interactive flood-fill visualizer

Flood animates flood fills on a canvas interactively, allowing the user to set each fill’s speed, data structure used to store coordinates of pixels that have been “seen” but have not yet been filled, and order in which neighboring pixels are enumerated and added to that data structure.

Several choices of data structure are provided, including the usual options of a stack (FIFO) or queue (LIFO). A recursively implemented flood fill is also provided, in such a way that (like the iteratively implemented approaches) it does not overflow the call stack even when used to fill a large region.

In effect, Flood is a rudimentary raster graphics editing canvas, whose “bucket tool” operates slowly and without blocking other edits to the canvas. As a flood fill proceeds, you can continue editing the canvas, interacting with the fill—including by starting additional concurrent flood fills.

This is alpha 6 of Flood. The program is not yet production quality, and it has some major bugs. See BUGS.md.

See also TreeTraversalAnimations.

Note: Flood’s built-in help retrieves fonts and JavaScript libraries from the internet every time it runs, even though Flood is not itself a webapp. This was convenient for development, but I do not regard it to be a good software engineering practice for a desktop application. So I consider this behavior a bug that must be fixed before putting out a non-alpha release of Flood. One would typically never notice this behavior, at least when running Flood with an active internet connection, since CDNs are very fast. But if it seems like Flood is “phoning home” while running, that’s what’s going on.

How to Use

Flood is a Windows program, implemented as a LINQPad query. To run Flood, clone this repository, then open flood.linq in LINQPad 6.

The program’s user interface is unfortunately not very intuitive. This is partly because it is an alpha version of the program; partly to do with its origin as a prototype for what I intended to be a separate, portable application with a different interface, which I still do hope also to write; and partly to do what I personally find intuitive and convenient, which is far from universal.

This README file provides only condensed documentation. For more documentation, including detailed usage guidance and implementation notes, please see the full help, doc/help.html, which can also be viewed in Flood’s built-in help browser or visited online.

When running Flood, you can also click the Show Tips button to open brief help, which I recommend. The tips are presented in condensed, tabular form. Hovering your mouse cursor over an item in the tips shows a tooltip with more information, and clicking on an item opens (or switches to) the built-in help browser, scrolling to the relevant section of the help and highlighting the specific relevant part.

The tips can also be browsed by going to doc/tips.html in a web browser, locally or on the web. When viewed that way, the items behave as ordinary hyperlinks into the full help.

License

Flood is free software. It is licensed under 0BSD (the “Zero-Clause BSD License,” also called the Free Public License 1.0.0). This license is very permissive; it is said to be “public-domain equivalent.”

See LICENSE.

Dependencies

Flood’s dependencies (other than LINQPad) are also free as in freedom, but they are offered under other licenses. Some of them are retrieved automatically via NuGet and cached; LINQPad will prompt you to do this unless you happen to already have those libraries. Others are downloaded automatically from CDNs (though in a future version I intend to bundle them instead).

See NOTICES.md, or the Dependencies section in doc/help.html, for a list of dependencies, with authorship and copyright/licensing information.

Acknowledgements

I’d like to thank:

  • David Vassallo, for testing the program and giving usability feedback.
  • Thomas Fallon, for testing the program and giving usability feedback, and finding a severe performance bug.
  • Zanna Star, for examining and giving advice about how to improve the presentation and styling for help.html. It was rather difficult to read before, and it is much better as a result of her suggestions.
  • Finlay McWalter, who created static flood-fill animations for “Flood fill” on English Wikipedia, demonstrating the effect of a stack vs. a queue, and other Wikipedians who have contributed to that article. McWalter’s animations were what inspired me to write this program.
  • The authors of the libraries and fonts this program uses, listed in NOTICES.md.

Goals

The main goals of Flood (besides being fun and looking cool) are to demonstrate two concepts in computer science:

  1. The flood fill algorithm: how it is really a graph traversal problem, and the way it is affected by choice of data structure and other related customizations.

  2. Asynchronous programming in the context of responsive user-interface interaction, and the way language-level features for asynchronous programming (like async/await in C#, which this program uses) facilitate code whose structure clearly reflects the problem being solved, much more so than if one were to code up a state machine manually.

The main reason I’ve written Flood a a LINQPad query is to make it easy to look at the source code while running the program, and to experiment by making changes to the source code re-running the program to see the difference. LINQPad displays Flood’s source code and its user interface side-by-side.

Reading the Code

Although ease of demonstration is sometimes a justification for cramming more source code into a single file than one otherwise would, this is currently excessive: the main source code file, flood.linq, is over 3500 lines. I regard this situation to be a bug and I intend to split that file into several files and/or make the code more easy to navigate in other ways. (LINQPad fully supports queries spanning multiple files, so that’s not the issue.)

The most interesting part of the code is the part that implements iterative flood fill as an asynchronous method. This is the FloodFillAsync method in the MainPanel class. See also the RecursiveFloodFillAsync method, which appears immediately after FloodFillAsync.

Non-Interacting and Interacting Fills

The kinds of animations you see, and what they reveal, depend on how you choose to use Flood. Two opposite patterns are of particular interest:

Independent

If you do at most one fill per region at a time, with only a stack or queue, and with only fixed-order neighbor enumeration, and you do not otherwise modify the canvas, the results resemble the static animations shown in the Moving the recursion into a data structure section of “Flood fill” (English Wikipedia).

I am grateful to Finlay McWalter, who made those animations, which inspired me to write this program. (I did not refer to McWalter’s source code in writing this, however.)

Interfering

When multiple concurrent flood fills are nested—with some working to fill a region that others are trying to expand—they can interact and interfere (“fight”) with each other. This is rarely relevant to practical applications of flood fills, since flood fills are usually carried out atomically rather than having their steps interleaved with other operations. But it can produce visually interesting patterns that take a long time to terminate, particularly when several (or perhaps many) different fills, of different kinds, interact.

I hadn’t anticipated that when I started working on this program, but I now consider it to be the most interesting use of the program, or at least the most fun.