Warning: session_start(): open(/var/lib/php/sessions/sess_m61dg0bi9lteqn6bvmgrahjj6m, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
srecord noeq G22RegionThinner(IImageRegion> originalRegion) is Steppable {
Rect bounds;
// true = part of region
// index is in bounds coordinates
bool[] pixels;
IImageRegion region = new {
public Rect bounds() { ret bounds; }
public bool contains(int x, int y) {
ret containsPt(bounds, x, y) && pixels[idx(x, y)];
}
public Iterator pixelIterator() {
ret iff_null(new IF0 {
int idx = 0;
public Pt get() {
for (; idx < pixels.length; idx++)
if (pixels[idx])
ret idxToPt(idx++);
null;
}
});
}
};
int idx(int x, int y) {
ret (y-bounds.y)*bounds.w+x-bounds.x;
}
Pt idxToPt(int idx) {
ret pt(bounds.x+(idx % bounds.w), bounds.y+idx/bounds.w);
}
void init {
if (bounds != null) ret;
bounds = originalRegion.bounds();
pixels = new bool[area(bounds)];
for (Pt p : itIt(originalRegion.pixelIterator()))
pixels[idx(p.x, p.y)] = true;
}
bool change;
public bool step() {
init();
change = false;
L traces = g22_allBorderTraces(region);
for (points : traces) {
if (eq(first(points), last(points))) removeLast(points);
for i over points: {
ping();
if (deletableBorderPoint(points, i)) {
Pt p = points.get(i);
pixels[idx(p.x, p.y)] = false;
set change;
}
}
points.clear();
}
ret change;
}
bool deletableBorderPoint(PtBuffer points, int i) {
L range = cyclicSubList(points, i-2, i+3);
Pt p = points.get(i);
// check all 8 points around border point
for (int dir = 1; dir <= 8; dir++) {
Pt p2 = ptPlus(p, onePathDirection(dir));
// If neighboring point is in region but not in current border,
// it makes the border point deletable
if (region.contains(p2.x, p2.y)
&& !range.contains(p2))
true;
}
false;
}
}