srecord noeq G22SkeletonWalker(IImageRegion region) is Steppable {
event foundLink(Pt a, Pt b);
settable int minDist = 3;
// point to "registered" point close by
new Map ptMap;
// TEMPORARY DATA
bool initialized;
// each pair is (registered point, point-to-explore)
new LinkedList> queue;
public bool step() {
// find first pixel
if (!initialized) {
set initialized;
Pt p = region.firstPixel();
if (p == null) false;
queue.add(pair(null, p));
}
if (empty(queue)) false;
Pair pair = popFirst(queue);
Pt prev = pair.a, p = pair.b;
Pt mapped = lookupOrKeep(ptMap, p);
bool seen = ptMap.containsKey(p);
Pt mapTo = p;
if (prev != null) {
if (distantEnough(prev, mapped))
foundLink(prev, mapped);
else
mapTo = prev;
}
if (!seen) {
ptMap.put(p, mapTo);
Pt linkFrom = mapTo;
for (int dir = 1; dir <= 8; dir++) {
Pt p2 = ptPlus(p, onePathDirection(dir));
if (region.contains(p2))
queue.add(pair(linkFrom, p2));
}
}
true;
}
bool distantEnough(Pt a, Pt b) {
ret a != null && b != null
&& (absDiff(a.x, b.x) >= minDist || absDiff(a.y, b.y) >= minDist);
}
}