Processing Geometry Suite
sobolLDS()
to PGS_PointSet
. Generates a set of 2D deterministic stratified points from the Sobol low discrepancy sequence.cluster()
to PGS_PointSet
. Clusters a collection points into N groups (using k-means).double[][]
conversion methods to PGS_Conversion
. Converts simple PShapes to and from their double[p1, p2, ...][x, y]
representation.weightedMedian()
to PGS_PointSet
. Finds the geometric median point of a set of weighted sample points.median()
to PGS_ShapePredicates
. Computes the geometric median location of a shape's vertices.isConformingMesh()
to PGS_ShapePredicates
. Determines whether a GROUP shape forms a conforming mesh / valid coverage.createRandomSFCurve()
to PGS_Construction
. Creates a random space-filling curve.createTaijitu()
to PGS_Construction
. Creates a Taijitu shape (a geometric representation of the Taoist symbol of yin and yang).createArbelos()
to PGS_Construction
. Creates an arbelos figure.createTeardrop()
to PGS_Construction
. Creates a teardrop figure.createGear()
to PGS_Construction
. Creates a gear figure.createSponge()
to PGS_Construction
. Creates a sponge-like porous structure.createRandomBezierPolygon()
to PGS_Construction
. Generates a smooth or spiky random polygon comprising Bezier curves.createSuperRandomPolygon()
to PGS_Construction
. Generates a highly customisable random polygon based on a square grid of cells.maximumPerimeterSquare()
to PGS_Optimisation
. Finds the largest square whose 4 vertices each lie on the perimeter of a shape.rectPack()
to PGS_Optimisation
. Packs a collection of rectangles into rectangular 2D bin(s).reorderChildren()
to PGS_Conversion
. Reorders the child shapes of a shape according to given comparator.scaleAreaTo()
to PGS_Transformation
. Scales a given shape to a target shape area.scaleArea()
to PGS_Transformation
. Scales the area of a given shape by a specified scale factor.circleCoverage()
to PGS_Optimisation
. Covers a polygon with n circles.PGS_Conversion.fromPVector()
that accepts a list of holes, each defined a list of by PVectors.simpleSubtract()
to PGS_ShapeBoolean
. Subtracts inner holes that lie within a given shell from the shell, without geometric processing.fromQuadraticBezier()
and fromCubicBezier()
to PGS_Conversion
. Makes a PATH shape representing a bezier curve (having equidistant sampling) given by its parameters.simplifyHobby()
to PGS_Morphology
. Creates a smooth Hobby Curve from the vertices of a shape.toPShape()
to PGS_Triangulation
. Converts a triangulated mesh object to a PShape representing the triangulation -- helpful when working with the raw mesh.extractHoles()
to PGS_Processing
. Extracts all the holes from a shape.PGS_Processing.fromPVector()
that accepts a random seed.visibilityPolygon()
to PGS_Optimisation
. Computes the area visible from a given point in a space, considering occlusions caused by obstacles.PGS_CirclePacking.stochasticPack()
that accepts a random seed.filterChildren()
to PGS_Processing
. Filters the children of a shape object based on a given Predicate function.fromGraph()
to PGS_Conversion
. Converts a graph consisting of PVectors and PEdges into a PShape by polygonizing its edges.smoothMesh()
to PGS_Meshing
. Smoothes a mesh via iterative weighted Laplacian smoothing.stochasticMerge()
to PGS_Meshing
. Randomly merges together adjacent faces of a mesh.areaMerge()
to PGS_Meshing
. Merges/dissolves small faces of a mesh into their neighboring faces.simplifyMesh()
to PGS_Meshing
. Simplifies the boundaries of the faces in a mesh while preserving the original mesh topology.nodeNonMesh()
to PGS_Meshing
. Transforms a non-conforming mesh shape into a conforming mesh via "noding".splitEdges()
to PGS_Meshing
. Splits each edge of a given mesh shape into a specified number of equal parts.subdivideMesh()
to PGS_Meshing
. Subdivides the faces of a mesh using the simple Catmull-Clark split approach.toCircles()
to PGS_Conversion
. Creates a PShape having circle geometries representing a collection of circles.fromPShape()
to PGS_SegmentSet
. Extracts a list of unique PEdge segments representing the given shape.stretch()
to PGS_SegmentSet
. Stretches segments in a list by a specified factor.nest()
to PGS_Processing
. Creates a nested shape having n levels of inner polygons.largestEmptyCircles()
to PGS_Optimisation
. Finds the N largest empty circles amongst a set of obstacle geometries within a boundary.PGS_CirclePacking.maximumInscribedPack()
that accepts a minimum radius threshold.getPolygonInteriorSegments()
to PGS_SegmentSet
. Retains line segments from a set of line segments that are wholly contained within a given shape.minimumAreaRectangle()
to PGS_Optimisation
. Computes the minimum-area rectangle that encloses a shape.binPack()
to PGS_Optimisation
. Packs irregular polygonal shapes into rectangular containers (bins).smoothEllipticFourier()
to PGS_Morphology
. Smoothes a shape using its elliptic fourier descriptors.efdSimilarity()
to PGS_ShapePredicates
. Quantifies the similarity between two shapes, using elliptic fourier descriptors.dissolve()
to PGS_SegmentSet
. Dissolves a collection of edges into a set of maximal-length linestrings.toCentroidDualGraph()
to PGS_Conversion
. Converts a mesh-like PShape into its centroid-based undirected dual-graph.isValid()
to PGS_ShapePredicates
. Checks if a PShape is valid, and reports the validation error if it is invalid.obstaclePack()
to PGS_CirclePacking
. Packs circles of varying radii within a given shape, whilst respecting pointal obstacles.align()
to PGS_Transformation
. Aligns one polygon shape to another, by finding the optimal transformation.extractInnerEdges()
to PGS_Meshing
. Extracts all inner edges from a mesh.centerLine()
to PGS_Contour
. Determines the longest center line passing through a given shape.PGS_Conversion.toWKB()
and .fromWKB()
that write/read the binary shape representation into a file.pointOnExteriorByDistance()
to PGS_Processing
. Extracts a point from the perimeter (exterior) of the given shape at some distance along its perimeter.RLF_BRUTE_FORCE_4COLOR
. Repeatedly calls (upto 250 times) the recursive largest-first (RLF) algorithm until a 4-coloring is found.PGS_Processing.equalParition()
. New algorithm is ~2x faster. Also removed precise
parameter from method signature (no longer necessary).PGS_Processing.simplifyDCE()
. New algorithm is much faster, particularly on large inputs.PGS_Processing.cleanCoverage()
. New algorithm is much faster, particularly on large inputs.toPVector()
now works on GROUP shapes (returning vertices from all child shapes).PGS_ShapePredicates.holes()
now supports GROUP shapes.PGS_Morphology.smoothGaussian()
now supports GROUP shapes.PGS_Hull.convexHull()
. New algorithm is faster, and particularly so on large input sizes.relaxations
parameter to innerVoronoi()
methods in PGS_Voronoi
. Performs Lloyd's relaxations leading to centroidal voronoi.System.currentTimeMillis()
with System.nanoTime()
. Helps the randomness of outputs when called quickly within a loop.PGS_ShapePredicates.maximumInteriorAngle()
.PGS_ShapeBoolean
methods now preserve the style of input shape a
in their output.PGS_createRandomPolygon
can now accept a random seed.PGS_CirclePacking.maximumInscribedPack()
. New algorithm is faster, particularly so on higher circle counts.miniumumBoundingRectangle()
to minimumWidthRectangle()
.intersectMesh()
and subtractMesh()
now fully preserve the styling of original mesh faces.PGS_Contour.medialAxis()
now returns dissolved maximal-length lines, rather than line segments only.PGS_Processing.tangentAngle()
values correspond to the angle that the tangent line makes with the positive x-axis (east), orientated clockwise, regardless of polygon orientation.prunePointsWithinDistance()
was making it much slower than it should have been.fromJava2D()
conversion.from
and to
arguments for interpolate()
were the wrong way round.PGS_Construction.createHeart()
were slightly squished in the vertical direction.PGS_ShapeBoolean.unionMesh()
now handles meshes with holes correctly (holes were filled in previously).PGS_Processing.extractPerimeter()
now behaves as expected when perimeter location values are negative.point[s]OnExterior()
methods could incorrectly produce offsets towards the interior of a shape. Such values will now always correspond to offset away from a shape's interior.PGS_ShapePredicates.holes()
now identifies and counts gaps in meshes as holes.splitQuadrangulation
were unclosed and are now closed polygons.PGS_Conversion.toGraph()
no longer adds a spurious closing edges on LINE shapes.The latest tag hosts the latest version of PGS, and is used to provide PGS as a library via the Processing contribution manager.
PGS_Hull
— a dedicated class for convex and concave hulls of polygons and point sets.PGS_SegmentSet
— a class that generates random sets of non-intersecting line segments.equalPartition()
to PGS_Processing
. Partitions a shape into N approximately equal area polygons.trapezoidPartition()
to PGS_Processing
. Partitions a shape into axis-aligned trazepoids.fromChildren()
to PGS_Conversion
. Creates a single GROUP parent shape from a list of child shapes.WKT
and WKB
conversion methods to PGS_Conversion
. Converts PShapes to and from their Well-Known Text / Well-Known Binary representation.Encoded Polyline
conversion methods to PGS_Conversion
. Converts PShapes to and from a Google Encoded Polyline representation.GeoJSON
conversion methods to PGS_Conversion
. Converts PShapes to and from a GeoJSON representation.toJava2D()
and fromJava2D()
to PGS_Conversion
. Converts PShapes to and from Java2D/java.awt shape objects.originScale()
to PGS_Transformation
. Scales a shape relative to the origin (0, 0).resizeByWidth()
and resizeByHeight()
to PGS_Transformation
. Resizes a shape to a given width/height, whilst resizing the height/width to maintain the original aspect ratio.resizeByMajorAxis()
to PGS_Transformation
. Resizes a shape (based on the longest axis of its envelope) to a given size.translateEnvelopeTo()
and translateCornerTo()
to PGS_Transformation
. These methods translate a shape based on its envelope.GENETIC
, which finds a coloring via a genetic algorithm.toGraph()
to PGS_Conversion
. Converts a shape to a (jGraphT) graph, representing its dual-graph (this method was previously private).fromGraph()
to PGS_Conversion
. Converts a (jGraphT) graph to a shape, using a Force-Directed placement algorithm.sphericity()
, elongation()
and maximumInteriorAngle()
to PGS_ShapePredicates
.findContainingShape()
to PGS_ShapePredicates
. Finds the child shape in a GROUP shape that contains a query point.overlap()
to PGS_ShapePredicates
. Measures the degree of mutual overlap between two shapes.equalsExact()
, equalsNorm()
and equalsTopo()
to PGS_ShapePredicates
. These methods test for equality between two shapes according to different criteria.createRectangularSpiral()
to PGS_Construction
. Creates a rectangular-shaped spiral.createBlobbie()
to PGS_Construction
. Creates a "blob"-like shape.largestEmptyCircle()
to PGS_Optimisation
. Finds the largest empty circle in a set of obstacle geometries.hilbertSort()
to PGS_PointSet
. Sorts a list of points according to their location on a Hilbert curve.tangentAngle()
to PGS_Processing
. Finds the angle a the line tangent to a shape at a certain point on its perimeter.variableBuffer()
to PGS_Morphology
. Buffers a shape with a buffer whose distance varies along the shape's perimeter.toGraph()
and toDualGraph()
to PGS_Triangulation
. Converts a triangulation mesh to a direct, or dual, (jGraphT) graph representation.chordalAxis()
to PGS_Contour
. Finds the chordal axis (a type of skeleton) of a shape.tangencyPack()
to PGS_CirclePacking
. Generates a circle packing having a pattern of tangencies specified by a triangulation.PGS_Construction
.poissonN()
to PGS_PointSet
. Produces as Poisson distribution having exactly N points.removeHiddenLines()
to PGS_Processing
. Removes hidden lines from a set of overlapping/occluded polygons.relativeNeighborFaces()
to PGS_Meshing
. Finds the relative neighbour faces of a triangulation.spannerFaces()
to PGS_Meshing
. Finds the relative neighbour faces of a greedy sparse spanner of a triangulation.minimumSpanningTree()
to PGS_PointSet
. Finds the Euclidean minimum spanning tree of a set of points.repulsionPack()
to PGS_CirclePacking
. Generates a circle packing of a shape via iterative pair-repulsion.simplifyDCE()
to PGS_Morphology
. Simplifies a shape using Discrete Curve Evolution.compoundVoronoi()
to PGS_Voronoi
. Creates a Voronoi diagram for a set of disjoint shapes.buffer()
that accepts a buffer style parameter.offsetCurvesInward()
that accepts a curves number parameter.intersectMesh()
and subtractMesh()
to PGS_ShapeBoolean
. Performs the associated boolean operations on mesh-like shapes, preserving individual faces during the operation (rather than dissolving remaining elements).dilationErosion()
to PGS_Morphology
. Applies a positive followed by a negative buffer (in a single operation).eliminateSlivers()
to PGS_Processing
. Removes narrow areas ("slivers") from a shape.reducePrecision()
to PGS_Morphology
. Reduces the precision of a shape, whilst ensuring the output shape is valid.distanceField()
to PGS_Contour
. Generates a contour map based on a distance field of a shape.hatchSubdivision()
to PGS_Tiling
. Randomly subdivides the plane into equal-width strips having varying lengths.squareTriangleTiling()
to PGS_Tiling
. Generates a non-periodic tiling, comprising squares and equilateral triangles.cleanCoverage()
to PGS_Processing
. Removes gaps and overlaps from meshes/polygon collections.sineWarp()
to PGS_Morphology
. Warps/perturbs a shape by displacing vertices according to a sine wave following the perimeter.hilbertSortFaces()
to PGS_Optimisation
. Sorts the faces of a GROUP shape according to hilbert curve index of each face's centroid coordinate.PGS_Processing
to PGS_Hull
.partition()
to convexPartition()
.PGS_Conversion.fromPShape()
(a major method used internally) now applies any shape affine transformations (such as rotate()
, scale()
, translate()
) to the resulting geometry.earCutTriangulation()
now uses JTS' implementation which supports inputs with holes.PGS_Morphology.smoothGaussian()
now uses a higher default resolution.PGS_Contour.straightSkeleton()
now supports multi-polygonal inputs and outputs faces (in addition to bones and branches, as before).PGS_Contour.straightSkeleton()
uses a different implementation that is ~50x faster!maximumInscribedRectangle()
to maximumInscribedAARectangle()
("axis-aligned").PGS_Optimisation.maximumInscribedRectangle()
now finds the maximum-area inscribed rectangle of arbitrary orientation.PGS_Transformation.touchScale()
now scales shapes that are contained within a larger shape.PGS_CirclePacking.maximumInstribedPack()
. New algorithm is perfectly accurate and is ~10x faster!PGS_Conversion.fromPVector()
now outputs an unclosed path shape if the input vertices are unclosed (rather than always treating the input as a closed polygon).PGS_Transformation.resize()
now resizes a shape with respect to its center.PGS_Morphology.smoothGaussian()
now supports polygons with holes.PGS_PointSet.poisson()
. New algorithm is faster and produces better quality point set outputs.PGS_Conversion()
(such as setAllFillColor()
) now return the (mutated) input (rather than being public void
), to help method chaining.snapHull()
now uses a JTS-based implementation which improves the range of output and meaningfulness of the snap parameter (now 0...1).PGS_ShapePredicates()
now output double
.createShape()
in the P2D renderer were passed to fromPShape()
(#55).slice()
would sometimes fail to return some rectangular slices on a concave input (and it's more robust too now).point(s)OnExterior()
methods.PFonts
).fromPShape()
now properly converts singular shapes consisting of multiple contours that in turn represent multiple polygons (#67). (Note boolean flag HANDLE_MULTICONTOUR
should be toggled to enabled this feature).createShape(TRIANGLE)
.edgeCollapse
and centroid
quadrangulation methods now respect shape/triangulation holes.earCutTriangulation(List<PVector> points)
from PGS_Triangulation
.isolinesFromGrid()
from PGS_Contour
(dependency too large).voronoiCirclesDiagram()
from PGS_Voronoi
(achieved by compoundVoronoi()
).voronoiCells()
from PGS_Voronoi
(replaced by innerVoronoi()
).voronoiDiagram(IncrementalTin tin)
from PGS_Voronoi
.Bonus: the size of the .jar has been reduced a lot by removing a couple of dependencies that had many transitive dependencies!
This is a large update that introduces 4 new geometry classes.
PGS_PointSet
— a class that generates sets of 2D points having a variety of different distributions and constraints.PGS_Coloring
— a class for intelligent coloring of meshes (or mesh-like shapes) such that no two adjacent faces have the same color, while minimising the number of colors used.PGS_Tiling
— a class for tiling, tessellation and subdivision of the plane using periodic or non-periodic geometric shapes.PGS_Meshing
- a class to host mesh generation methods (excluding triangulation).toPointsPShape()
to PGS_Conversion
. Generates a POINTS
type PShape from a list of PVector points.delaunayTriangulation()
that accept a PShape only, returning a constrained triangulation.minimumBoundingTriangle()
to PGS_Optimisation
. Computes the minimum-area bounding triangle that encloses a shape or point set.unionMesh()
to PGS_ShapeBoolean
. Quickly and efficiently unions/merges the faces of a mesh-like shape together.setAllStrokeToFillColor()
to PGS_Conversion
. Sets the stroke color to the fill color for a PShape and all its descendants (separately).copy()
to PGS_Conversion
. Deep copies / clones a PShape.PGS_Construction
: serpinskiCurve, linearSpiral, fermatSpiral.extractPerimeter()
to PGS_Processing
. Extracts a portion/subline of the perimeter of a shape between two locations.interpolate()
to PGS_Morphology
. Generates an intermediate shape between two shapes by interpolating/morphing between them.PGS_Construction
now preserves a PShape's fillColor, strokeColor and strokeWeight throughout forward-backward conversion. This behaviour can be toggle using the class's PRESERVE_STYLE
flag (default = true). Note that PGS' methods will generally not preserve the style of the original PShape because JTS does not preserve geometry user data during its operations.fieldWarp()
now supports POINTS
and GROUP
PShapes.removeSmallHoles()
, round()
and chaikinCut()
now support GROUP
PShape inputs.partition()
, split()
and slice()
(from PGS_Processing
) now output a single GROUP
PShape (rather than a list of PShapes).PATH
(rather than GEOMETRY
) to maximise compatibility with the P2D
renderer.PGS_Contour.isolines()
now accepts a contour smoothing parameter.PGS_Processing.polygonizeLines()
is now more robust and faster.urquhartFaces()
and gabrielFaces()
from PGS_Triangulation
to PGS_Meshing
.micycle.pgs.utility
package to micycle.pgs.commons
.GROUP
PShape input.PGS_Contour.straightSkeletonSolub()
(didn't meet robustness standards)diameter()
to PGS_ShapePredicates
. Computes the diameter of a shape.width()
and height()
to PGS_ShapePredicates
.createRing()
to PGS_Construction
. Generates ring-shaped PShapes.roundVertexCoords()
to PGS_Conversion. Rounds the x and y coordinates of all vertices belonging to a shape.PGS_Triangulation.urquhartFaces()
. The new approach is typically ~3.5x faster!polygonizeLines()
now returns a GROUP
PShape (where each face is a child shape), rather than List<PShape>
.offsetCurvesOutwards()
(outer-most lines are now noticeably more smooth).offsetCurvesOutward()
now supports multi polygons (GROUP PShapes).PoissonDistribution
; poisson point outputs are now more densely packed and more regularly spaced.GROUP
PShapes, so individual triangles are more easily accessible.PGS_Triangulation.gabrielFaces()
no longer retains some edges that should have been removed according to the Gabriel graph condition.ELLIPSE
primitives.GROUP
PShapes containing multiple shape types (such as line and polygon).offsetCurvesInward()
applied to GROUP
PShapes no longer has a line joining shape islands.polygonizeLines()
to PGS_Processing
. Computes the polygonal faces formed by a set of intersecting line segments.PGS_Processing.generateRandomGridPoints()
that accepts a random seed.fieldWarp()
to PGS_Morphology
. Warps a shape by displacing vertices according to a 2D noise vector field.radialWarp()
to PGS_Morphology
. Warps a shape by displacing vertices along a line between each vertex and the shape centroid.TRIANGLES
PShape➜JTS MultiPolygon
QUADS
PShape➜JTS MultiPolygon
PGS_Transformation.rotateAroundCenter()
.voronoiCells()
to PGS_Voronoi
. Generates Voronoi diagrams from shapes or point sets, outputting the diagram as polygonal cells (rather than lines only, as before).voronoiDiagram()
that accepts a list of points (rather than PShapes only, as before).findContainedPoints()
to PGS_ShapePredicates
. Tests each point in a given point set whether it is contained in a shape, returning only those points that are contained.List<PVector>
method arguments to Collection<PVector>
where possible.generateRandomPoints()
no longer skips over small subsections of shapes when generating random points.PGS_CirclePacking
— a class for circle packings of shapes, subject to varying constraints and patterns of tangenciesclosestPointPair()
to PGS_Optimisation
. Efficiently computes the closest pair of points in a set of points.farthestPointPair()
to PGS_Optimisation
. Efficiently computes the farthest pair of points in a set of points.chaikinCut()
to PGS_Morphology
. Smoothes shapes via iterated corner cuts.createHeart()
to PGS_Construction
. Generates heart-shaped PShapes.urquhartFaces()
to PGS_Triangulation
. Tesselates a triangulation into polygons corresponding to the faces of an Urquhart graph.gabrielFaces()
to PGS_Triangulation
. Tesselates a triangulation into polygons corresponding to the faces of an Gabriel graph.earCutTriangulation()
accepts a PShape argument (previously it accepted a list of points only)generateRandomPoints()
that accepts a random seed.PGS_Conversion
to support conversion between:
PATH
PShape<->JTS LineString
POINTS
PShape<->JTS MultiPoint
LINES
PShape<->JTS MultiLineString
PGS_Processing.concaveHull()
into concaveHullDFS()
and concaveHullBFS()
(the method previously used the BFS approach only).PGS_Voronoi.voronoiCirclesDiagram()
PGS_Processing.generateRandomPoints()
with a triangulation-based approach. The new approach is ~10x faster!delaunayTriangulationTin()
to delaunayTriangulationMesh()
.poissonTriangulation()
to poissonTriangulationPoints()
(the method of the same original name now outputs a PShape).concaveHull2()
was called with alpha > 1.PGS_Conversion.toPVector()
now handles primitive PShapesPGS_Processing.concaveHull()
(see Changed)The first release😀.
Download the .jar from here to use PGS as a library within Processing.
A notable behavior (yet inconsequential for most users) at the moment is that GROUP
PShapes (i.e. PShapes with multiple children) are flattened (unioned) before being processed. If this is behavior is ever problematic to you, then iterate over the child PShapes individually, calling the method for each one.