/** * Sets the cell at point to "on". Does nothing if point is out of bounds, or if point is null. * More efficient, slightly, than {@link #set(boolean, Coord)} if you just need to set a cell to "on". * @param point the x,y Coord of the cell * @return this for chaining */ public GreasedRegion insert(Coord point) { if(point == null) return this; return insert(point.x, point.y); }
for (int i = 0; i < aLen; i++) { int volume = 10 + (height * width) / (aLen * 2); area.empty().insert(pts[i]).spill(bounds, volume, rng).expand(3); tmpInner.remake(area).retract(4).expand8way().and(area); tmpEdge.remake(area).surface8way();
public GreasedRegion insertCircle(Coord center, int radius) { float high, changedX; int rndX, rndY; for (int dx = -radius; dx <= radius; ++dx) { changedX = dx - 0.25f * Math.signum(dx); rndX = Math.round(changedX); high = (float) Math.sqrt(radius * radius - changedX * changedX); insert(center.x + rndX, center.y); for (float dy = high; dy >= 0.75f; --dy) { rndY = Math.round(dy - 0.25f); insert(center.x + rndX, center.y + rndY); insert(center.x + rndX, center.y - rndY); } } return this; }
@Override public boolean add(Coord coord) { if(contains(coord)) return false; insert(coord); return true; } @Override
protected void setFresh(int idx, int x, int y) { if(!initialized) return; fresh.get(idx).add(Coord.get(x, y)); anyFreshMap.insert(x, y); }
protected void setFresh(int idx, final Coord pt) { if(!initialized) return; if(anyFreshMap.contains(pt.x, pt.y)) return; fresh.get(idx).add(pt); anyFreshMap.insert(pt); }
spillMap[cell.x][cell.y] = i; filled++; anySpillMap.insert(cell.x, cell.y);
GreasedRegion remaining = new GreasedRegion(this); while (fst >= 0) { GreasedRegion filled = new GreasedRegion(width, height).insert(fst).flood8way(remaining, width * height); scattered.add(filled); remaining.andNot(filled);
spillMap[cell.x][cell.y] = i; filled++; anySpillMap.insert(cell.x, cell.y);
GreasedRegion remaining = new GreasedRegion(this); while (fst >= 0) { GreasedRegion filled = new GreasedRegion(width, height).insert(fst).flood(remaining, width * height); scattered.add(filled); remaining.andNot(filled);
/** * Meant for making maps conform to the Mollweide (elliptical) projection that MimicMap uses. * @param rectangular A GreasedRegion where "on" represents land and "off" water, using any rectangular projection * @return a reprojected version of {@code rectangular} that uses an elliptical projection */ public static GreasedRegion reprojectToElliptical(GreasedRegion rectangular) { int width = rectangular.width, height = rectangular.height; GreasedRegion t = new GreasedRegion(width, height); double yPos, xPos, th, thx, thy, lon, lat, ipi = 1.0 / Math.PI, rx = width * 0.25, irx = 1.0 / rx, hw = width * 0.5, ry = height * 0.5, iry = 1.0 / ry; yPos = -ry; for (int y = 0; y < height; y++, yPos++) { thx = asin((yPos) * iry); lon = (thx == Math.PI * 0.5 || thx == Math.PI * -0.5) ? thx : Math.PI * irx * 0.5 / NumberTools.cos(thx); thy = thx * 2.0; lat = asin((thy + NumberTools.sin(thy)) * ipi); xPos = 0; for (int x = 0; x < width; x++, xPos++) { th = lon * (xPos - hw); if (th >= -3.141592653589793 && th <= 3.141592653589793 && rectangular.contains((int) ((th + 1) * hw), (int) ((lat + 1) * ry))) { t.insert(x, y); } } } return t; }
public GreasedRegion removeIsolated() { int fst = firstTight(); GreasedRegion remaining = new GreasedRegion(this), filled = new GreasedRegion(this); while (fst >= 0) { filled.empty().insert(fst).flood(remaining, 8); if(filled.size() <= 4) andNot(filled); remaining.andNot(filled); fst = remaining.firstTight(); } return this; }
working.empty().insert(scatter[i]).spill(floors, rng.between(4, Math.min(remainingWater, sizeWaterPools)), rng); if (remainingGrass > 5) //remainingGrass >= targetGrass * 0.02 && working.empty().insert(scatter[i]).spill(floors, rng.between(4, Math.min(remainingGrass, sizeGrassPools)), rng); if (working.isEmpty()) continue;
/** * Finds the largest contiguous area of "on" cells in this GreasedRegion and returns it; does not modify this * GreasedRegion. If there are multiple areas that are all equally large with no larger area, this returns the * region it checks first and still is largest (first determined by the same ordering {@link #nth(int)} takes). * This may return an empty GreasedRegion if there are no "on" cells, but it will never return null. * Here, contiguous means adjacent on any 8-way direction, and considers cells as part of a contiguous area even if * all connections but one, which can be orthogonal or diagonal, are blocked by "off" cells. * @return a new GreasedRegion that corresponds to the largest contiguous sub-region of "on" cells in this. */ public GreasedRegion largestPart8way() { int fst = firstTight(), bestSize = 0, currentSize; GreasedRegion remaining = new GreasedRegion(this), filled = new GreasedRegion(width, height), choice = new GreasedRegion(width, height); while (fst >= 0) { filled.empty().insert(fst).flood8way(remaining, width * height); if((currentSize = filled.size()) > bestSize) { bestSize = currentSize; choice.remake(filled); } remaining.andNot(filled); fst = remaining.firstTight(); } return choice; }
/** * Finds the largest contiguous area of "on" cells in this GreasedRegion and returns it; does not modify this * GreasedRegion. If there are multiple areas that are all equally large with no larger area, this returns the * region it checks first and still is largest (first determined by the same ordering {@link #nth(int)} takes). * This may return an empty GreasedRegion if there are no "on" cells, but it will never return null. * Here, contiguous means adjacent on an orthogonal direction, and this doesn't consider diagonally-connected cells * as contiguous unless they also have an orthogonal connection. * @return a new GreasedRegion that corresponds to the largest contiguous sub-region of "on" cells in this. */ public GreasedRegion largestPart() { int fst = firstTight(), bestSize = 0, currentSize; GreasedRegion remaining = new GreasedRegion(this), filled = new GreasedRegion(width, height), choice = new GreasedRegion(width, height); while (fst >= 0) { filled.empty().insert(fst).flood(remaining, width * height); if((currentSize = filled.size()) > bestSize) { bestSize = currentSize; choice.remake(filled); } remaining.andNot(filled); fst = remaining.firstTight(); } return choice; }
working.empty().insert(scatter[i]).spill(floors, rng.between(4, Math.min(remainingWater, sizeWaterPools)), rng); if (remainingGrass > 5) //remainingGrass >= targetGrass * 0.02 && working.empty().insert(scatter[i]).spill(floors, rng.between(4, Math.min(remainingGrass, sizeGrassPools)), rng); if (working.isEmpty()) continue;