// Abstract base class for tiling an image (G22Tiling)
abstract srecord noeq G22AbstractTiler
(Img image) is Runnable, Steppable {
delegate Tile to G22Tiling.
int w, h, runner;
gettable int size; // =w*h
// iterator that provides points to be looked at
// (e.g. a WeightlessShuffledIterator)
IndexIterator pointIterator;
// Temporary stack of points to be looked at
// (e.g. neighbors of a tile just discovered).
// May or may not be used.
new IntBuffer stack;
G22Tiling
tiling; // the tiling we are making
int tileCounter;
GrowTile growingTile; // tile currently being grown
bool verbose;
// The one method subclasses need to override.
// The exact meaning of a "color" is not defined,
// the tiler just treats different int value as different colors.
abstract int getColor(int pos);
// calculations for positions (pixel index)
int x(int pos) { ret pos % w; }
int y(int pos) { ret pos / w; }
int pos(int x, int y) { ret y*w+x; }
Pt pt(int pos) { ret Pt(x(pos), y(pos)); }
bool validPos(int x, int y) { ret x >= 0 && y >= 0 && x < w && y < h; }
class GrowTile is Steppable {
Tile tile;
// Still growing in each of the 4 directions?
bool growingN = true;
bool growingE = true;
bool growingS = true;
bool growingW = true;
*(int pos) {
int x = x(pos), y = y(pos);
int iTile = tileCounter++;
tile = new Tile;
tile.position = rect(x, y, 1, 1);
tiling.tiles.add(tile);
tiling.tileMatrix[pos] = iTile+1;
}
public bool step() {
false;
}
}
run { stepAll(this); }
public bool step() {
init();
// Currently growing a tile? Continue that
if (growingTile != null) {
if (growingTile.step()) true;
growingTile = null; // Done growing this tile
}
int pos = pointIterator.nextIndex();
if (pos < 0) false;
// Is point already covered by a tile?
if (tiling.tileMatrix[pos] != 0) true;
// Create new tile
growingTile = new GrowTile(pos);
true;
}
void init {
if (tiling != null) ret;
w = image.getWidth(); h = image.getHeight();
size = w*h;
tiling = new G22Tiling(image);
tiling.initTileMatrix();
pointIterator = WeightlessShuffledIterator(size);
}
G22Tiling
get() {
if (tiling == null) run();
ret tiling;
}
}