From ed8a14ee099bded2f56925f4c6f6dade4e4ef5b6 Mon Sep 17 00:00:00 2001 From: tosh Date: Wed, 27 Mar 2013 03:33:51 +0100 Subject: [PATCH] adds flood fill algorithm --- shared/src/FloodFill.h | 96 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 shared/src/FloodFill.h diff --git a/shared/src/FloodFill.h b/shared/src/FloodFill.h new file mode 100644 index 0000000000..a63bcad936 --- /dev/null +++ b/shared/src/FloodFill.h @@ -0,0 +1,96 @@ +// +// FloodFill.h +// hifi +// +// Created by Tobias Schwinger 3/26/13. +// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. +// + +#ifndef __hifi__FloodFill__ +#define __hifi__FloodFill__ + +/** + * Line scanning, iterative flood fill algorithm. + */ +template< class Strategy, typename Cursor > +void floodFill(Cursor const& position, + Strategy const& strategy = Strategy()); + + +template< class Strategy, typename Cursor > +struct floodFill_impl : Strategy +{ + floodFill_impl(Strategy const& s) : Strategy(s) { } + + using Strategy::select; + using Strategy::process; + + using Strategy::left; + using Strategy::right; + using Strategy::up; + using Strategy::down; + + using Strategy::defer; + using Strategy::deferred; + + void go(Cursor position) + { + Cursor higher, lower, h,l, i; + bool higher_found, lower_found, hf, lf; + do + { + if (! select(position)) + continue; + + process(position); + + Cursor higher = position, lower = position; + bool higher_found = false; + bool lower_found = false; + up(higher); yTest(higher, higher_found); + down(lower); yTest(lower, lower_found); + + i = position, h = higher, l = lower; + hf = higher_found, lf = lower_found; + do { right(i), right(h), right(l); yTest(h,hf); yTest(l,lf); } + while (selectAndProcess(i)); + + i = position, h = higher, l = lower; + hf = higher_found, lf = lower_found; + do { left(i); left(h); left(l); yTest(h,hf); yTest(l,lf); } + while (selectAndProcess(i)); + } + while (deferred(position)); + } + + bool selectAndProcess(Cursor const& i) + { + if (select(i)) + { + process(i); + return true; + } + return false; + } + + void yTest(Cursor const& i, bool& state) + { + if (! select(i)) + state = false; + else if (! state) + { + state = true; + defer(i); + } + } +}; + +template< class Strategy, typename Cursor > +void floodFill(Cursor const& p, Strategy const& s) +{ + floodFill_impl(s).go(p); +} + + +#endif +