Skip to content

Commit

Permalink
Add TestBuilder truchetTiling function
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-jts committed Nov 23, 2024
1 parent 40b7b91 commit 6c99023
Showing 1 changed file with 59 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
import org.locationtech.jts.geom.Envelope;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.PrecisionModel;
import org.locationtech.jts.geom.util.AffineTransformation;
import org.locationtech.jts.operation.polygonize.Polygonizer;
import org.locationtech.jts.precision.GeometryPrecisionReducer;
import org.locationtech.jts.shape.random.RandomPointsBuilder;
import org.locationtech.jts.shape.random.RandomPointsInGridBuilder;
import org.locationtech.jtstest.geomfunction.Metadata;
Expand Down Expand Up @@ -354,4 +358,59 @@ private static Coordinate randomPtInRectangleAround(Coordinate centre, double wi
return new Coordinate(x0, y0);
}

/**
* Truchet tiling created from a base (lower-left) tile defined by from set of lines.
* The tiles are copied to a square grid of size nSide,
* and rotated by a random multiple of 90 degrees.
* The tile line endpoints are snapped to a precision grid to make them align.
* If tiling is to be polygonized lines should be noded and snapped to edge points.
*
* @param tileLines set of lines defining base tile
* @param nSide number of tiles per side of tiling
* @return lines for tiling.
*/
@Metadata(description="Create Truchet tiling from lines defining lower left tile")
public static Geometry truchetTiling(Geometry tileLines,
@Metadata(title="Grid side cell #")
int nSide) {
PrecisionModel pmSnap = new PrecisionModel(10000.0);
//Geometry tileSnap = snapEndpoints(tileLines.copy(), pmSnap);
Geometry tileSnap = GeometryPrecisionReducer.reduce(tileLines, pmSnap);
Envelope env = tileSnap.getEnvelopeInternal();
int side = (int) Math.max(env.getHeight(), env.getWidth());
Coordinate centre = env.centre();

List<Geometry> tiles = new ArrayList<Geometry>();
for (int i = 0; i < nSide; i++) {
for (int j = 0; j < nSide; j++) {
//-- random rotation by PI/2, translate to grid cell
int nPi2 = (int) (4 * Math.random());
AffineTransformation trans = AffineTransformation.rotationInstance(nPi2 * Math.PI / 2.0,
centre.getX(), centre.getY());
trans.translate(i * side, j * side);

Geometry tileTrans = tileSnap.copy();
//-- don't transform base tile
if (i > 0 || j > 0) {
tileTrans.apply(trans);
}
//Geometry tileTransSnap = snapEndpoints(tileTrans, pmSnap);
Geometry tileTransSnap = GeometryPrecisionReducer.reduce(tileTrans, pmSnap);
tiles.add(tileTransSnap);
}
}
//-- close tiling and polygonize
double baseX = env.getMinX();
double baseY = env.getMinY();
Envelope tilingEnv = new Envelope(baseX, baseX + nSide * side, baseY, baseY + nSide * side);
Geometry tilingBdy = tileLines.getFactory().toGeometry(tilingEnv).getBoundary();
tiles.add(tilingBdy);
Geometry tileLinesGeom = tileLines.getFactory().buildGeometry(tiles);
Geometry allLines = tileLinesGeom.union();
//System.out.println(allLines);
Polygonizer polygonizer = new Polygonizer();
polygonizer.add(allLines);
return polygonizer.getGeometry();
}

}

0 comments on commit 6c99023

Please sign in to comment.