Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PGS 2.0 (Java 17) #94

Draft
wants to merge 20 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,29 @@ 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.0** *(2023-xx-xx)*

### Added
* `findShortestTour()` to `PGS_PointSet`. Computes an <i>approximate</i> Traveling Salesman path for a set of points.
* `pruneSparsePoints()` to `PGS_PointSet`. Prunes a list of points by removing points that are considered not sufficiently dense (far away from their nearest neighbours); a counterpart to `prunePointsWithinDistance()`.
* Additional method signature for `PGS_Morphology.variableBuffer()` that accepts a callback function to define the buffer value at each vertex.
* `boundsCenter()` to `PGS_Transformation`. Computes the center of the bounding box of a shape.
* Additional method signature for `delaunayTriangulation(points)` that supports a boundary constraint.
* `fix()` to `PGS_Processing`. Attempts to fix shapes with invalid geometry.
* Additional method signature for `frontChainPack()` that accepts a random seed.

### Changes
* Packed circles from `PGS_CirclePacking.stochasticPack()` will now always lie within a shape bounds.
* `PGS_Processing.pointsOnExterior()` methods now respect GROUP shapes and holes (inner rings) and will populate them with points.
* `PGS_Morphology.simplifyDCE()` now supports GROUP shapes and polygon holes.

### Fixed
* `urquhartFaces()`, `relativeNeighborFaces()`, `gabrielFaces()` and `spannerFaces()` from `PGS_Meshing` now preserve holes from the input.

### Removed
* `simplifyDCE(shape, targetNumVertices)` and `simplifyDCE(shape, vertexRemovalFraction)` in favour a single method that accepts a user-defined termination callback that is supplied with the current vertex candidate's coordinate, relevance score, and the number of vertices remaining.


## **1.4.0** *(2023-07-29)*

### Added
Expand Down
32 changes: 17 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,41 +13,41 @@ Docs are hosted via *GitHub Pages* [here](https://micycle1.github.io/PGS/).
Library functionality is split over the following classes:

* `PGS_CirclePacking`
* Circle packings of shapes, subject to varying constraints and patterns of tangencies
* Circle packings of shapes, subject to varying constraints and patterns of tangencies.
* `PGS_Coloring`
* Minimal colorings of meshes (or mesh-like shapes)
* Minimal colorings of meshes (or mesh-like shapes).
* `PGS_Construction`
* Construct uncommon/interesting 2D primitives
* Construct uncommon/interesting 2D primitives.
* `PGS_Contour`
* Methods that produce various contours from shapes: medial axes, straight skeletons, offset curves, etc.
* `PGS_Conversion`
* Conversion between *Processing* PShapes and *JTS* Geometries (amongst other formats)
* `PGS_Hull`
* Convex and concave hulls of polygons and point sets
* Convex and concave hulls of polygons and point sets.
* `PGS_Meshing`
* Mesh generation (excluding triangulation) and processing
* Mesh generation (excluding triangulation) and processing.
* `PGS_Morphology`
* Methods that affect the geometry or topology of shapes (buffering, simplification, smoothing, etc.)
* Methods that affect the geometry or topology of shapes (buffering, simplification, smoothing, etc.).
* `PGS_Optimisation`
* Solve geometric optimisation problems, such as finding the maximum inscribed circle, or the closest vertex to a coordinate
* 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
* Generates sets of 2D points having a variety of different distributions and constraints.
* `PGS_Processing`
* Methods that process a shape in some way: compute hulls, partition, slice, etc.
* Methods that process a shape in some way: partition, slice, clean, etc.
* `PGS_SegmentSet`
* Generates sets of random non-intersecting line segments
* Generates sets of random non-intersecting line segments.
* `PGS_ShapeBoolean`
* Boolean set-operations for 2D shapes
* Boolean set-operations for 2D shapes.
* `PGS_ShapePredicates`
* Various shape metrics (area, circularity, etc.) and predicates (*"do these shapes intersect?"*)
* Various shape metrics (area, circularity, etc.) and predicates (*"do these shapes intersect?"*).
* `PGS_Tiling`
* Tiling, tessellation and subdivision of the plane using periodic or non-periodic geometric shapes.
* `PGS_Transformation`
* Various geometric and affine transformations that affect vertex coordinates
* Various geometric and affine transformations that affect vertex coordinates.
* `PGS_Triangulation`
* Delaunay triangulation (constrained and refined) and earcut triangulation of shapes and point sets
* Delaunay triangulation (constrained and refined) and earcut triangulation of shapes and point sets.
* `PGS_Voronoi`
* Voronoi Diagrams of shapes and point sets
* Voronoi Diagrams of shapes and point sets.

## **Installation**

Expand Down Expand Up @@ -842,11 +842,13 @@ Much of the functionality (but by no means all) is demonstrated below:
</tr>
<tr>
<td align="center" valign="center"><b>EMST</td>
<td align="center" valign="center"><b>Shortest Tour (TSP)</td>
<td align="center" valign="center"><b>Cluster</td>
<td align="center" valign="center"><b>Weighted Median</td>
</tr>
<tr>
<td valign="top" width="25%"><img src="resources/point_set/emst.png"></td>
<td valign="top" width="25%"><img src="resources/point_set/tsp.png"></td>
<td valign="top" width="25%"><img src="resources/point_set/cluster.png"></td>
<td valign="top" width="25%"><img src="resources/point_set/weightedMedian.png"></td>
</tr>
Expand Down
9 changes: 5 additions & 4 deletions examples/contourMap/contourMap.pde
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ List<PVector> heights;
float max = -1, min = 9999;
UniformNoise noise;

final int RESOLUTION = 16; // lower is more resolution
final int RESOLUTION = 15; // lower is more resolution

void setup() {
size(800, 800, FX2D);
size(1000, 1000, FX2D);
smooth();
noise = new UniformNoise();
}
Expand All @@ -30,6 +30,7 @@ void draw() {
map(isoline.getVertex(0).x, 0, width, 50, 255),
map(isoline.getVertex(0).y, 0, height, 50, 255)
));
isoline.setStrokeWeight(3);
shape(isoline);
}
}
Expand All @@ -39,8 +40,8 @@ void populateHeightMap() {

final float animSpeed = 0.005;

for (int x = 0; x <= width; x+=RESOLUTION) {
for (int y = 0; y <= height; y+=RESOLUTION) {
for (int x = 0; x <= width+RESOLUTION; x+=RESOLUTION) {
for (int y = 0; y <= height+RESOLUTION; y+=RESOLUTION) {
float z = noise.uniformNoise(x*0.0055 + frameCount*animSpeed, y*0.0055 + frameCount*animSpeed, 2, 0.5);
PVector h = new PVector(x, y, 0);

Expand Down
17 changes: 12 additions & 5 deletions examples/drawOffsetCurves/drawOffsetCurves.pde
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ PShape shape;
boolean inward = true;

void setup() {
size(800, 800, FX2D);
size(1000, 1000, FX2D);
smooth();
textAlign(CENTER, CENTER);

Expand All @@ -29,7 +29,8 @@ void draw() {

colorMode(HSB, 1);
for (int i = 0; i < offsetCurves.getChildCount(); i++) {
offsetCurves.getChild(i).setStroke(color((float) mouseY/height, ((float) i / (offsetCurves.getChildCount()-1)) + 0.1, 1));
color c = color((float) mouseY/height, ((float) i / (offsetCurves.getChildCount()-1)) + 0.1, 1);
PGS_Conversion.setAllStrokeColor(offsetCurves.getChild(i), c, 2);
}
colorMode(RGB, 255);

Expand All @@ -38,13 +39,19 @@ void draw() {
textSize(36);
text("Use mouse to draw!", width/2, height/2);
textSize(14);
text("Press any key to switch between inward/outward style.", width/2, height/2 + 30);
text("LEFT mouse = add; RIGHT mouse = subtract.", width/2, height/2 + 30);
text("Press any key to switch between inward/outward style.", width/2, height/2 + 60);
}
}

void mouseDragged() {
shape = PGS_ShapeBoolean.union(shape, createShape(ELLIPSE, mouseX, mouseY, 100, 100));
shape = PGS_Morphology.simplify(shape, 1);
if (mouseButton == LEFT) {
shape = PGS_ShapeBoolean.union(shape, createShape(ELLIPSE, mouseX, mouseY, 75, 75));
} else if (mouseButton == RIGHT) {
shape = PGS_ShapeBoolean.subtract(shape, createShape(ELLIPSE, mouseX, mouseY, 75, 75));
}
shape = PGS_Morphology.simplify(shape, 0.1);
PGS_Conversion.setAllFillColor(shape, 255);
PGS_Conversion.disableAllStroke(shape);
}

Expand Down
40 changes: 32 additions & 8 deletions examples/ripplingTriangles/ripplingTriangles.pde
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,32 @@ import java.util.List;
import micycle.pgs.*;
import micycle.uniformnoise.*;
import java.util.concurrent.atomic.AtomicInteger;
import net.jafama.FastMath;


PShape triangles; // triangle lattice arranged in a hexagon pattern
boolean warp = true;
UniformNoise noise;

void setup() {
size(800, 800, FX2D);
size(1000, 1000, FX2D);
smooth();
textAlign(LEFT, TOP);

noise = new UniformNoise(1337);
triangles = PGS_Triangulation.delaunayTriangulation(PGS_PointSet.hexagon(width/2, height/2, 9, 45));
triangles = PGS_Triangulation.delaunayTriangulation(PGS_PointSet.hexagon(width/2, height/2, 19, 30));
triangles = PGS_Morphology.buffer(triangles, -2);
frameRate(600);
}

void draw() {
colorMode(RGB, 255, 255, 255, 255);
background(0, 0, 40);
//background(0, 0, 40);
fill(0,0,40,33);
rect(0,0,width,height);

fill(0, 255, 255);
text(frameRate, 2, 2); // fps
//text(frameRate, 2, 2); // fps

colorMode(HSB, 1, 1, 1, 1);

Expand All @@ -41,12 +45,13 @@ void draw() {
triangle = PGS_Transformation.translate(triangle, (hue - 0.5f) * 100, (-hue + 0.5f) * 100);

if (warp) {
triangle = PGS_Morphology.fieldWarp(triangle, 11, .11, millis() * 0.0005f, true, 1337);
triangle = PGS_Morphology.simplify(triangle, 1);
triangle = PGS_Morphology.fieldWarp(PGS_Processing.densify(triangle, 5), 11, .11, millis() * 0.0005f, !true, 1337);
triangle = PGS_Morphology.simplify(triangle, 0.75);
}

PGS_Conversion.setAllFillColor(triangle, color(hue, 1, 0.6f, 0.6f));
PGS_Conversion.setAllStrokeColor(triangle, color(hue, 1, 1), 4);

PGS_Conversion.setAllFillColor(triangle, setAlpha(sinebow(hue), 85)); // color(hue, 1, 0.6f, 0.6f)
PGS_Conversion.setAllStrokeColor(triangle, sinebow(hue), 3);

return triangle;
}).sequential().forEach(t -> shape(t));
Expand All @@ -59,3 +64,22 @@ void mousePressed() {
void keyPressed() {
warp = !warp;
}

public static int setAlpha(int c, int alpha) {
return (c & 16777215) | alpha << 24;
}

public static int sinebow(double t) {
t = 0.5f - t;
return rgbColor(255 * (sin2(t + 0 / 3f)),
255 * (sin2(t + 1 / 3d)), 255 * (sin2(t + 2 / 3d)));
}

private static double sin2(double t) {
double z = FastMath.sin(PI * t);
return z * z;
}

public static int rgbColor(double red, double green, double blue) {
return -16777216 | FastMath.roundToInt(red) << 16 | FastMath.roundToInt(green) << 8 | FastMath.roundToInt(blue);
}
13 changes: 8 additions & 5 deletions examples/slice/slice.pde
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ void draw() {
background(0, 0, 40);

if ((frameCount-1) % 180 == 0) {
polygon = PGS_Construction.createRandomPolygon((int) random(3, 7), width, height);
polygon = PGS_Construction.createSuperRandomPolygon(width, choice(5,50) , random(0.05, 0.2), choice(0, 3), choice(1, 3), false, true, millis());
polygon = PGS_Transformation.resizeByMajorAxis(polygon, 666);
polygon = PGS_Transformation.translateEnvelopeTo(polygon, width/2, height/2);
}

slice(polygon);
Expand All @@ -26,16 +28,17 @@ void slice(PShape shape) {
PShape slices = PGS_Processing.slice(shape, pv1, pv2);
PShape s = slices.getChild(0);
PShape s2 = slices.getChild(1);

PGS_Conversion.setAllFillColor(s, color(237, 50, 162));
PGS_Conversion.setAllStrokeColor(s, color(237, 50, 162), 4);
PGS_Conversion.setAllStrokeColor(s, color(237, 50, 162), 3);
PGS_Conversion.setAllFillColor(s2, color(255));
//PGS_Conversion.setAllStrokeColor(s2, color(237, 50, 162), 3);

shape(s);
shape(s2);

strokeWeight(5);
stroke(0, 0, 40);
stroke(255, 255, 0, 100);
line(pv1.x, pv1.y, pv2.x, pv2.y);
stroke(color(237, 50, 162));
strokeWeight(15);
Expand Down
6 changes: 3 additions & 3 deletions examples/spiralOutline/spiralOutline.pde
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ PShape triangles;
UniformNoise noise;

void setup() {
size(800, 800, FX2D);
size(1000, 1000, FX2D);
smooth();
colorMode(HSB, 1, 1, 1);
rectMode(CORNER);
Expand All @@ -17,15 +17,15 @@ void setup() {
}

void draw() {
fill(0, 0, 0.1, 64);
fill(0, 0, 0.05, 64);
rect(0, 0, width, height);

PShape spiral = PGS_Construction.createLinearSpiral(width/2, height/2, 0.5+mouseX/200f, 250+mouseY/5f);
spiral = PGS_Transformation.rotate(spiral, new PVector(width/2, height/2), frameCount/100f);
spiral.setFill(false);
shape(spiral);

spiral = PGS_Morphology.simplify(spiral, 1);
spiral = PGS_Morphology.simplify(spiral, .1);
spiral = PGS_Morphology.buffer(spiral, 20);

int perimeters = 30; // perimeter sections
Expand Down
2 changes: 1 addition & 1 deletion jitpack.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
jdk:
- openjdk8
- openjdk17
18 changes: 8 additions & 10 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>micycle</groupId>
<artifactId>PGS</artifactId>
<version>1.4.0</version>
<version>2.0-SNAPSHOT</version>
<name>Processing Geometry Suite</name>
<description>Geometric algorithms for Processing</description>

Expand All @@ -20,10 +20,9 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<version>3.12.1</version>
<configuration>
<source>8</source>
<target>8</target>
<release>17</release>
</configuration>
</plugin>
<plugin>
Expand All @@ -43,10 +42,9 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<version>3.6.3</version>
<configuration>
<failOnError>false</failOnError>
<source>8</source>
<subpackages>micycle.pgs</subpackages>
<excludePackageNames>micycle.pgs.color</excludePackageNames>
</configuration>
Expand Down Expand Up @@ -202,8 +200,8 @@
<dependencies>
<dependency>
<groupId>com.github.micycle1</groupId>
<artifactId>processing3</artifactId>
<version>3.5.4</version>
<artifactId>processing-core-4</artifactId>
<version>4.3</version>
<scope>provided</scope> <!-- don't package into uber jar -->
<optional>true</optional> <!-- user artifact should override when provided -->
</dependency>
Expand All @@ -220,7 +218,7 @@
<dependency>
<groupId>org.jgrapht</groupId>
<artifactId>jgrapht-core</artifactId>
<version>1.4.0</version> <!-- 1.5+ requires Java 11 -->
<version>1.5.2</version>
</dependency>
<dependency>
<groupId>org.tinfour</groupId>
Expand All @@ -245,7 +243,7 @@
<dependency>
<groupId>org.tinspin</groupId>
<artifactId>tinspin-indexes</artifactId>
<version>1.7.1</version>
<version>2.1.3</version>
</dependency>
<dependency> <!-- for test running -->
<groupId>org.junit.jupiter</groupId>
Expand Down
Binary file added resources/point_set/tsp.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading