Skip to content
Draft

2.2 #153

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
880b6fd
add fixBrokenFaces()
micycle1 Oct 5, 2025
fc000b3
closestPoint always boundary (+ other small)
micycle1 Oct 20, 2025
7c8167c
isovist small improvements
micycle1 Oct 20, 2025
b5c2421
remove polygonizeLines(List<PVector>); add polygonize
micycle1 Oct 21, 2025
d5763be
refactor the various edge collapse methods
micycle1 Oct 27, 2025
9161d6f
fix GENETIC coloring
micycle1 Oct 27, 2025
ebdc223
reducePrecision on group shapes
micycle1 Oct 28, 2025
9ff67ca
swap to jts MBT
micycle1 Nov 3, 2025
f224a3c
add softCells
micycle1 Nov 7, 2025
cf53e47
fix #161
micycle1 Dec 16, 2025
8a7c306
reimplement convex partition (Keil & Snoeyink)
micycle1 Dec 16, 2025
cc80d8d
add DBLAC coloring
micycle1 Dec 17, 2025
ffd071b
add DBLAC code
micycle1 Dec 17, 2025
0293d1b
convex partition - handle degenerate
micycle1 Dec 20, 2025
b67dfae
add smoothGaussianNormalised
micycle1 Dec 20, 2025
c323f03
add normalisedErosion
micycle1 Dec 20, 2025
4e398ca
fix SRPG
micycle1 Dec 20, 2025
2592e58
two small bugs
micycle1 Dec 21, 2025
dd1386f
add contour regularization source
micycle1 Dec 21, 2025
0240cb9
small
micycle1 Dec 21, 2025
48694ed
add refine().
micycle1 Dec 27, 2025
5c36d14
reimplement tsp
micycle1 Dec 28, 2025
c95c02d
format tsp
micycle1 Dec 28, 2025
cc3935b
improve class javadocs
micycle1 Dec 28, 2025
a49c291
remove unionMeshWithoutHoles()
micycle1 Dec 28, 2025
ee1206a
treat closed linestrings as non-areal
micycle1 Dec 29, 2025
699891a
add arap()
micycle1 Dec 29, 2025
b766b42
add regularise()
micycle1 Dec 29, 2025
28cdc3b
touchup compoundVoronoi
micycle1 Dec 30, 2025
ce4858f
jts coveragecleaner
micycle1 Dec 30, 2025
6cd85bc
copy shape name during style transfer
micycle1 Dec 30, 2025
ab3dd83
remove trapmap from pip test
micycle1 Dec 30, 2025
bf14443
javadocs and imports
micycle1 Dec 30, 2025
4fd8cd9
List -> Collection; some javadocs
micycle1 Jan 1, 2026
63b901d
improve tests
micycle1 Jan 1, 2026
3fa02be
remove COARSE
micycle1 Jan 1, 2026
c693625
commit polygonisation
micycle1 Jan 2, 2026
13e6d10
various improvements
micycle1 Jan 2, 2026
0e14ed1
finalise polygonisation
micycle1 Jan 2, 2026
c26e5be
wkt digits
micycle1 Jan 4, 2026
95a90a7
FLOAT_SAFE_MESH_CONVERSION
micycle1 Jan 4, 2026
266f5d4
add ring morpher..
micycle1 Jan 9, 2026
f0a2363
swap out interpolation algorithm
micycle1 Jan 9, 2026
ad41d3e
add smoothBezierFit()
micycle1 Jan 10, 2026
e9c728d
add powerDiagram()
micycle1 Jan 11, 2026
62dc343
init manhatten voronoi
micycle1 Jan 11, 2026
2357466
manhatten voronoi - envelope bounds
micycle1 Jan 12, 2026
992403b
manhatten voronoi - optimise (remove currying etc)
micycle1 Jan 12, 2026
13f0e27
add manhattenVoronoi()
micycle1 Jan 12, 2026
fe5c1f6
polygonisation image color profiles
micycle1 Jan 12, 2026
a39eba2
cleanup shapeIntersection()
micycle1 Jan 13, 2026
a097d87
fix random points for hole polygons
micycle1 Jan 13, 2026
3ad027e
add squareGrid()
micycle1 Jan 13, 2026
0ee4a2b
add azteDiamond
micycle1 Jan 15, 2026
e1f633b
add ppSegments()
micycle1 Jan 16, 2026
ec6190c
add aztecd + other
micycle1 Jan 16, 2026
b02523c
no message
micycle1 Jan 16, 2026
b7a67eb
assorted
micycle1 Jan 17, 2026
b0b39ce
javadocs
micycle1 Jan 18, 2026
696c59d
add hausdorffInterpolate()
micycle1 Jan 19, 2026
f41b39a
add voronoimorph
micycle1 Jan 21, 2026
71047b1
init marchingsquares
micycle1 Jan 22, 2026
2aded58
add isolinesFromFunction() (and improve distanceField())
micycle1 Jan 23, 2026
93a7c5c
add kCenters()
micycle1 Jan 23, 2026
33b3891
toGraph() and fromGraph() handle holes
micycle1 Jan 26, 2026
8ad4394
reimplement LEC
micycle1 Feb 1, 2026
3b8a575
assorted
micycle1 Feb 1, 2026
939473e
extractPerimeter tests
micycle1 Feb 1, 2026
20f3568
PGS_Conversion UNAMBIGUOUS POLYGON/LINESTRING
micycle1 Feb 1, 2026
0a85272
fix various spelling errors
micycle1 Feb 1, 2026
ece7129
Conversion -- don't fill LinearRing (treat as linear)
micycle1 Feb 1, 2026
d5e8579
rework applyToLinealGeometries()
micycle1 Feb 1, 2026
6b7f69f
add extractBoundary
micycle1 Feb 2, 2026
f43dee2
use FastVariableBuffer
micycle1 Feb 2, 2026
d94904c
add weaveSegments()
micycle1 Feb 2, 2026
186cb3d
add auxeticTiling()
micycle1 Feb 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 66 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,71 @@ All notable changes to PGS will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Dates are *YYYY-MM-DD*.

## **2.2** *(2026-xx-xx)*

### Added
#### Classes
* **`PGS_Polygonisation`** — generates simple polygonisations of point sets.

#### Methods
* `fixBrokenFaces()` to `PGS_Meshing`. Repairs broken faces in near-coverage linework using endpoint-only snapping, then polygonises the result.
* `polygonize()` to `PGS_Processing`. Finds polygonal faces from the given shape's linework.
* `softCells()` to `PGS_Tiling`. Generates a softened (curved) version of a tiling using the SoftCells edge-bending algorithm.
* A new mesh-coloring algorithm: `DBLAC`, it's even better than RLF!
* `smoothGaussianNormalised()` to `PGS_Processing`. Applies normalised Gaussian smoothing to all geometries in a shape, intended to be more consistent across child shapes of different sizes.
* `normalisedErosion()` to `PGS_Morphology`. Erodes a shape by a normalised amount (scaled to shape size).
* `refine()` to `PGS_Triangulation`. Refines an existing triangulation using Ruppert's Delaunay refinement algorithm.
* `arapDeform()` to `PGS_Morphology`. Applies As-Rigid-As-Possible (ARAP) shape deformation using point handles.
* `regularise()` to `PGS_Morphology`. Straightens the contour of a shape by snapping edges toward a small set of principal directions.
* New method signature for `PGS_Conversion.toWKT()` that accepts a precision parameter to control the number of decimal places written.
* `smoothBezierFit()` to `PGS_Morphology`. Smoothes a shape by fitting Bezier curves to its vertices.
* `powerDiagram()` to `PGS_Voronoi`. Generates a Power Voronoi Diagram for a set of weighted sites.
* `manhattanVoronoi()` to `PGS_Voronoi`. Generates a Manhattan Voronoi Diagram for a set of sites and a bounding box.
* `intersectionPoints(shape)` to `PGS_Processing`. Computes all self-intersection points of the linework contained within a single shape.
* `intersections()` to `PGS_SegmentSet`. Computes all intersection points among the supplied edges.
* `squareGrid()` to `PGS_Tiling`. Divides the plane into a simple axis-aligned grid using square cells.
* `aztecDiamond()` to `PGS_Tiling`. Produces a random domino tiling of the Aztec diamond of a given order.
* `perpendicularPathSegments()` to `PGS_SegmentSet`. Extracts perpendicular segments along each linear component of shape, with each segment centered on the path/outline.
* `dilationMorph()` to `PGS_Morphology`. Morphs between two shapes using a Hausdorff-distance based method.
* `voronoiMorph()` to `PGS_Morphology`. Morphs between two shapes using a Voronoi-based method.
* `isolinesFromFunction()` to `PGS_Contour`. Extracts contour lines (isolines) from a user-defined 2D “height map” over a rectangular region.
* `kCenters()` to `PGS_PointSet`. Selects k points from the input to act as centers that are typically well distributed over the input space.
* `extractBoundary()` to `PGS_Processing`. Extracts the topological boundary of the given shape.
* `weaveSegments()` to `PGS_SegmentSet`. Creates a fabric-like layout of horizontal and vertical segments.
* `auxeticTiling()` to `PGS_Tiling`. Builds a tiling of interlocking cells that form an auxetic structure.

### Changes
* `PGS_Conversion.fromPShape()` now disambiguates closed paths using the PShape’s `kind`: closed shapes with `kind == POLYGON` convert to JTS `Polygon`, while closed shapes with `kind == PATH` convert to a (closed) JTS `LineString` (previously closed paths were generally treated as polygonal).
* `PGS_Conversion.toPShape()` now encodes polygon-vs-line semantics by setting the output PShape’s `kind` appropriately (`POLYGON` for JTS polygonal geometries; `PATH` for JTS lineal geometries), so closed linework no longer becomes ambiguous on round-trip.
* These methods in `PGS_Meshing` are more performant and robust: `urquhartFaces()`, `gabrielFaces()`, `spannerFaces()`, `relativeNeighborFaces()`, `edgeCollapseQuadrangulation()`, `centroidQuadrangulation()`.
* Reimplemented `PGS_Processing.convexPartition()` using the optimal *Keil & Snoeyink* partitioning algorithm.
* Reimplemented `PGS_PointSet.findShortestTour()` TSP algorithm. Much faster (~50x) on larger inputs.
* `PGS_Meshing.fixBreaks()` now uses a JTS implementation under the hood. The method's prior `angleTolerance` arg has been removed as it's no longer necessary.
* A PShape's original `.name` is now included in the `PRESERVE_STYLE` routines.
* All methods in `PGS_Morphology` now support GROUP shapes (where it makes sense to).
* `PGS_Conversion.toWKT()` now writes coordinates in float precison by default (previously 2 decimal places).
* Reimplemented `PGS_Morphology.interpolate()` using a more advanced approach with better quality (though interpolations can still self-intersect).
* Renamed `shapeIntersection(a, b)` in `PGS_Processing` to `intersectionPoints()`.
* Reimplemented `PGS_Morphology.distanceField()` with a better quality approach, and added an additional method signature that accepts a 'pole' parameter to compute the distance field with respect to a specific point.
* `largestEmptyCircles()`, `maximumInscribedPack()` and `obstaclePack()` are slightly faster.

### Fixed
* `PGS_Optimisation.closestPoint()` now returns the nearest location on the shape's **boundary** for queries inside a polygonal shape (previously returned the query point itself).
* `GENETIC` mesh-coloring algorithm now always works (and has been improved too).
* `PGS_Morphology.reducePrecision()` now supports GROUP shapes without collapsing them.
* `PGS_Construction.createSuperRandomPolygon()` no longer produces holes when `holes` is set to `false`.
* `PGS_Contour.chordalAxis()` can no longer return polygonal output.
* `PGS_Voronoi.compoundVoronoi()` now uses the given bounds (previously ignored).
* `PGS_Processing.generateRandomPoints()` can no longer produce different outputs for the same seed on polygons with holes.
* The `toGraph()` and `fromGraph()` methods in `PGS_Conversion` now correctly handle shapes with holes.

### Removed
* `polygonizeLines()` from `PGS_Processing`, in favour of `polygonize(PShape)`.
* `unionMeshWithoutHoles()` from `PGS_ShapeBoolean`. Previously deprecated in favour of the more general `unionMesh()`.
* `fromGeoJSON()` and `toGeoJSON()` from `PGS_Conversion`.
* The `COARSE` mesh coloring algorithm, since it can color adjacent faces the same colour.
* `lineSegmentsIntersection()` from `PGS_ShapeBoolean` in favour of `intersectionPoints(PShape)`.

## **2.1** *(2025-10-04)*

### Added
Expand Down Expand Up @@ -46,6 +111,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* `pruneRandomRemoveN()` to `PGS_PointSet`. Randomly removes exactly N points from a list of points.
* `pruneRandomToN()` to `PGS_PointSet`. Randomly prunes a list of points to exactly N points.
* `convexMaximumInscribedCircle()` to `PGS_Optimisation`. Computes the largest inscribed circle of a convex polygon (faster and exact).
* `dissolve()` to `PGS_Processing`. Dissolves the linear components of a shape into a set of unique maximal-length lines

### Changes
* Optimised `PGS_CirclePacking.tangencyPack()`. It's now around 1.5-2x faster and has higher precision.
Expand All @@ -65,7 +131,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* `PGS_Processing.pointsOnExterior()` methods now return points on all elements of a shape, not just the perimeter of the first polygon.
* `PGS_Processing.segmentsOnExterior()` now return segments on all elements of a shape, not just the perimeter of the first polygon.
* These methods in `PGS_Morphology` now process any and all polygon/line elements in a shape: `chaikinCut()`, `smoothGaussian()`, `simplifyDCE()`, `simplifyHobby()`, `smoothEllipticFourier()`, `round()`.
* `dissolve()` to `PGS_Processing`. Dissolves the linear components of a shape into a set of unique maximal-length lines

### Fixed
* `PGS_Morphology.rounding()` no longer gives invalid results.
Expand Down
112 changes: 106 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ Library functionality is split over the following classes:
* Solve geometric optimisation problems, such as finding the maximum inscribed circle, or the closest vertex to a coordinate.
* `PGS_PointSet`
* Generates sets of 2D points having a variety of different distributions and constraints.
* `PGS_Polygonisation`
* Generates simple polygonisations of point sets.
* `PGS_Processing`
* Methods that process a shape in some way: partition, slice, clean, etc.
* `PGS_SegmentSet`
Expand Down Expand Up @@ -246,6 +248,13 @@ Much of the functionality (but by no means all) is demonstrated below:
<tr>
<td align="center" valign="center">A contour map based on a distance field of a shape</td>
</tr>
<tr>
<td align="center" valign="center" colspan="2"><b>Isolines from function</td>
</tr>
<tr>
<td valign="top"><img src="resources/contour/isolinesFromFunction1.gif"></td>
<td valign="top"><img src="resources/contour/isolinesFromFunction2.gif"></td>
</tr>
</table>

## *Morphology*
Expand Down Expand Up @@ -319,9 +328,24 @@ Much of the functionality (but by no means all) is demonstrated below:

<tr>
<td align="center" valign="center"><b>Pinch Warp</td>
<td align="center" valign="center"><b>ARAP Deform</td>
<td align="center" valign="center"><b>Regularise</td>
<td align="center" valign="center"><b>Bezier-fit Smoothing</td>
</tr>
<tr>
<td valign="top" width="25%"><img src="resources/morphology/pinchWarp.gif"></td>
<td valign="top" width="25%"><img src="resources/morphology/arapMorph.gif"></td>
<td valign="top" width="25%"><img src="resources/morphology/regularise.gif"></td>
<td valign="top" width="25%"><img src="resources/morphology/smoothBezierFit.gif"></td>
</tr>

<tr>
<td align="center" valign="center"><b>Dilation Morph</td>
<td align="center" valign="center"><b>Voronoi Morph</td>
</tr>
<tr>
<td valign="top" width="25%"><img src="resources/morphology/dilationMorph.gif"></td>
<td valign="top" width="25%"><img src="resources/morphology/voronoiMorph.gif"></td>
</tr>
</table>

Expand Down Expand Up @@ -473,13 +497,16 @@ Much of the functionality (but by no means all) is demonstrated below:

<tr>
<td align="center" valign="center"><b>Poisson Delaunay Triangulation</td>
<td align="center" valign="center"><b>Refinement</td>
</tr>
<tr>
<td valign="top" width="25%"><img src="resources/contour/poissonTriangulation.gif"></td>
<td valign="top" width="25%"><img src="resources/triangulation/refine.gif"></td>
</tr>

<tr>
<td align="center" valign="center"><i>Delaunay triangulation</i> of shapes where <i>steiner points</i> generated by poisson disk sampling are inserted.</td>
<td align="center" valign="center">Ruppert angle refinement.</td>
</tr>
</table>

Expand All @@ -497,15 +524,23 @@ Much of the functionality (but by no means all) is demonstrated below:
<td valign="top" width="25%"><img src="resources/voronoi/compoundLines.png"></td>
</tr>
<tr>
<td align="center" valign="center"><b>Centroidal Relaxation</td>
<td align="center" valign="center"><b>Manhattan Voronoi</td>
<td align="center" valign="center"><b>Power Diagram</td>
<td align="center" valign="center"><b>Multiplicatively Weighted Voronoi</td>
<td align="center" valign="center"><b>Farthest-Point Voronoi</td>
</tr>
<tr>
<td valign="top" width="25%"><img src="resources/voronoi/centroidal.gif"></td>
<td valign="top" width="25%"><img src="resources/voronoi/manhattenVoronoi.gif"></td>
<td valign="top" width="25%"><img src="resources/voronoi/powerDiagram.gif"></td>
<td valign="top" width="25%"><img src="resources/voronoi/mwvd.gif"></td>
<td valign="top" width="25%"><img src="resources/voronoi/fpvd.gif"></td>
</tr>
<tr>
<td align="center" valign="center"><b>Centroidal Relaxation</td>
</tr>
<tr>
<td valign="top" width="25%"><img src="resources/voronoi/centroidal.gif"></td>
</tr>
</table>

## *Meshing*
Expand Down Expand Up @@ -887,9 +922,11 @@ Much of the functionality (but by no means all) is demonstrated below:
</tr>
<tr>
<td align="center" valign="center"><b>Distance Prune</td>
<td align="center" valign="center"><b>k Centers</td>
</tr>
<tr>
<td valign="top" width="25%"><img src="resources/point_set/removeWithinDistance.gif"></td>
<td valign="top" width="25%"><img src="resources/point_set/kCenters.gif"></td>
</tr>
</table>

Expand All @@ -909,11 +946,15 @@ Much of the functionality (but by no means all) is demonstrated below:
</tr>
<tr>
<td align="center" valign="center"><b>Parallel</td>
<td align="center" valign="center"><b>Perpendicular Path Segments</td>
<td align="center" valign="center"><b>Polygon Interior Segments</td>
<td align="center" valign="center"><b>weave Segments</td>
</tr>
<tr>
<td valign="top" width="25%"><img src="resources/segment_set/parallel.gif"></td>
<td valign="top" width="25%"><img src="resources/segment_set/perpendicularPathSegments.gif"></td>
<td valign="top" width="25%"><img src="resources/segment_set/interiorSegments.png"></td>
<td valign="top" width="25%"><img src="resources/segment_set/weaveSegments.gif"></td>
</tr>
</table>

Expand All @@ -933,32 +974,91 @@ Much of the functionality (but by no means all) is demonstrated below:
<td valign="top" width="25%"><img src="resources/tiling/hatchSubdivision.png"></td>
</tr>
<tr>
<td align="center" valign="center"><b>Islamic Tiling</td>
<td align="center" valign="center"><b>Square Grid</td>
<td align="center" valign="center" colspan="2"><b>Doyle Spiral</td>
<td align="center" valign="center"><b>Hexagon Tiling</td>
</tr>
<tr>
<td valign="top" width="25%"><img src="resources/tiling/islamic.png"></td>
<td valign="top" width="25%"><img src="resources/tiling/grid.png"></td>
<td valign="top" width="25%"><img src="resources/tiling/doyeSpiral1.png"></td>
<td valign="top" width="25%"><img src="resources/tiling/doyeSpiral2.png"></td>
<td valign="top" width="25%"><img src="resources/tiling/hex.png"></td>
</tr>
<tr>
<td align="center" valign="center"><b>Islamic Tiling</td>
<td align="center" valign="center"><b>Penrose Tiling</td>
<td align="center" valign="center"><b>Square-Triangle Tiling</td>
<td align="center" valign="center"><b>Annular Bricks</td>
<td align="center" valign="center"><b>Slice Division</td>

</tr>
<tr>
<td valign="top" width="25%"><img src="resources/tiling/islamic.png"></td>
<td valign="top" width="25%"><img src="resources/tiling/penrose.png"></td>
<td valign="top" width="25%"><img src="resources/tiling/stTiling.png"></td>
<td valign="top" width="25%"><img src="resources/tiling/annularBricks.png"></td>
<td valign="top" width="25%"><img src="resources/tiling/sliceDivision.png"></td>
</tr>
<tr>
<td align="center" valign="center"><b>Slice Division</td>
<td align="center" valign="center"><b>Arc Division</td>
<td align="center" valign="center"><b>Soft Cells</td>
<td align="center" valign="center"><b>Aztec Diamond</td>
</tr>
<tr>
<td valign="top" width="25%"><img src="resources/tiling/sliceDivision.png"></td>
<td valign="top" width="25%"><img src="resources/tiling/arcDivision.png"></td>
<td valign="top" width="25%"><img src="resources/tiling/softCells.gif"></td>
<td valign="top" width="25%"><img src="resources/tiling/aztecDiamond.png"></td>
</tr>
<tr>
<td align="center" valign="center" colspan="2"><b>Auxetic Tiling</td>
</tr>
<tr>
<td valign="top" width="25%"><img src="resources/tiling/auxetic1.png"></td>
<td valign="top" width="25%"><img src="resources/tiling/auxetic2.png"></td>
</tr>
</table>

<section id="polygonisation">
<h2>Polygonisation</h2>

<table>
<tr>
<td align="center" valign="center"><b>Max Area</b></td>
<td align="center" valign="center"><b>Min Area</b></td>
<td align="center" valign="center"><b>Min Perimeter (TSP)</b></td>
<td align="center" valign="center"><b>Hilbert</b></td>
</tr>
<tr>
<td valign="top" width="25%"><img src="resources/polygonisation/maxArea.png" alt="maxArea"></td>
<td valign="top" width="25%"><img src="resources/polygonisation/minArea.png" alt="minArea"></td>
<td valign="top" width="25%"><img src="resources/polygonisation/minPerimeter.png" alt="minPerimeter"></td>
<td valign="top" width="25%"><img src="resources/polygonisation/hilbert.png" alt="hilbert"></td>
</tr>

<tr>
<td align="center" valign="center"><b>Horizontal</b></td>
<td align="center" valign="center"><b>Vertical</b></td>
<td align="center" valign="center"><b>Circular</b></td>
<td align="center" valign="center"><b>Angular</b></td>
</tr>
<tr>
<td valign="top" width="25%"><img src="resources/polygonisation/horizontal.png" alt="horizontal"></td>
<td valign="top" width="25%"><img src="resources/polygonisation/vertical.png" alt="vertical"></td>
<td valign="top" width="25%"><img src="resources/polygonisation/circular.png" alt="circular"></td>
<td valign="top" width="25%"><img src="resources/polygonisation/angular.png" alt="angular"></td>
</tr>

<tr>
<td align="center" valign="center"><b>Onion</b></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td valign="top" width="25%"><img src="resources/polygonisation/onion.png" alt="onion"></td>
<td valign="top" width="25%"></td>
<td valign="top" width="25%"></td>
<td valign="top" width="25%"></td>
</tr>
</table>
</section>
Loading