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); } }