Giter Club home page Giter Club logo

pgs's Introduction

Lines of Code

Processing Geometry Suite

Processing Geometry Suite is a software project that provides easy access to 2D geometric algorithms in the form of a Processing library. Over time it has grown to include an incredibly comprehensive range of algorithms.

The focus of the library is on visualisation rather than providing underlying data structures. To this end all methods in the library are static and most of them take in and return PShapes or PVectors.

Docs are hosted via GitHub Pages here.

Overview

Library functionality is split over the following classes:

  • PGS_CirclePacking
    • Circle packings of shapes, subject to varying constraints and patterns of tangencies
  • PGS_Coloring
    • Minimal colorings of meshes (or mesh-like shapes)
  • PGS_Construction
    • 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
  • PGS_Meshing
    • Mesh generation (excluding triangulation) and processing
  • PGS_Morphology
    • 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
  • PGS_PointSet
    • 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.
  • PGS_SegmentSet
    • Generates sets of random non-intersecting line segments
  • PGS_ShapeBoolean
    • Boolean set-operations for 2D shapes
  • PGS_ShapePredicates
    • 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
  • PGS_Triangulation
    • Delaunay triangulation (constrained and refined) and earcut triangulation of shapes and point sets
  • PGS_Voronoi
    • Voronoi Diagrams of shapes and point sets

Installation

Processing IDE — Quick

Download the latest PGS.jar from releases and simply drag-and-drop it onto the Processing IDE.

Processing IDE — Permanently

Download the latest PGS.jar from releases and save it to Documents\Processing\libraries\PGS\library.

Result: Documents\Processing\libraries\PGS\library\PGS.jar.

(Note the .jar and the folder must be called PGS — rename the .jar if this is not the case).

Maven/Gradle

PGS is hosted as an artifact for use in Maven or Gradle projects via Jitpack — follow the instructions there (very easy).

Examples

A number of example Processing sketches are provided in examples.

Illustrations

Much of the functionality (but by no means all) is demonstrated below:

2D Boolean Operations

Union Intersection Subtraction Symmetric Difference
Complement Mesh Union Mesh Intersection Mesh Subtraction

Transformation

Rotate Around Translate To Touch Scale
Rotate a shape around its centroid or an arbitrary point. Translate a shape such that its centroid matches some position. Scale one shape such that it touches another.
Resize Homothetic Transformation Shear Align
Projection-transform a shape with respect to a fixed point. Maximum-overlap alignment.

Geometric Predicates & Metrics

Intersects Contains Shape Contains Point Containing Cell

Do shapes intersect with each other?

Does one shape fully contain another?

For individual points and point sets.

Which cell contains the query point?

Metrics

  • Length/perimeter
  • Width & Height
  • Diameter
  • Circularity
  • Similarity
  • Sphericity
  • Elongation
  • Density
  • Holes
  • Maximum interior angle
  • Is simple?
  • Is convex?
  • Equal? (structural and topological equivalence)
  • Distance
  • Area
  • Centroid
  • Median

Contour

Isolines Offset Curves
Isolines from intra-shape euclidean distance, or point sets. Inner and exterior offset curves; based on miter, bevel or round offset styles.
Straight Skeleton Medial Axis Chordal Axis
Medial axis transform with feature pruning via distance, area or axial angle. Chordal Axis Transform
Distance Field Center Line
A contour map based on a distance field of a shape

Morphology

Buffer Erosion-Dilation Minkowski Addition
A negative followed by a positive buffer (in a single operation). Minkowski sum and difference (a.k.a buffer one shape using another shape; the examples add a rotating & growing triangle).
Smoothing Gaussian Smoothing Rounding
Radial Warp Sine Warp Field Warp
Simplification Chaikin Cutting Interpolation
Variable Buffer Precision Reduction Hobby Curve Simplification Elliptic Fourier Smoothing

Hull

Concave Hull Convex Hull of Polygons
Concave hull of point sets via breadth-first or depth-first approaches.
Convex Hull Snap Hull
A variable-convexity hull.

Geometry Processing

Points on Perimeter Point on Perimeter Perimeter Extraction
Find N points (evenly distributed) along the perimeter of a shape, or points every D distance (with optional perpendicular offset). Find a point some fraction along the perimeter of a shape (with perpendicular offset).
Splitting Convex Partitioning Equal Partitioning Trapezoid Partitioning
Subdivide (recursively) a shape into quadrants. Partition a shape into convex polygons. Partition a shape into N equal area polygons.
Slicing Constrained Random Point Set Segment Set Intersection
Slice a shape in two along a given line. Generate constrained random point sets where all points lie within a shape. Find all points of intersection between a collection of line segments.
Shape Intersection Polygonize Lines Hidden Line Removal
Find all points of intersection between two shapes. Find the polygonal faces formed by a set of intersecting line segments. Remove linework occulted by shapes (for pen plotting)
Densification Tangent Angle Eliminate Slivers Clean Coverage
Extract Holes Nest

Triangulation

Delaunay Triangulation Earcut Triangulation
Poisson Delaunay Triangulation
Delaunay triangulation of shapes where steiner points generated by poisson disk sampling are inserted.

Voronoi Diagrams

Voronoi Diagram (inner) Voronoi Diagram (compound)
Centroidal Relaxation

Meshing

Urquhart Faces Gabriel Faces Triangulation Dual
Polygon faces of an Urquhart Graph (derived from a triangulation). Polygon faces of a Gabriel Graph (derived from a triangulation).
Relative Neighbour Faces Spanner Faces Centroid Quadrangulation Edge Collapse Quadrangulation
Split Quadrangulation Spiral Quadrangulation Mesh Smoothing Mesh Subdivision
Mesh Simplification Stochastic Merge Area Merge Extract Inner Edges

Geometric Optimisation

Maximum Inscribed Circle Minimum Bounding Rectangle Maximum Inscribed Rectangle Maximum Perimeter Square
Minimum Bounding Circle Minimum Bounding Ellipse
Minimum Bounding Triangle Envelope Problem of Apollonius
Largest Empty Circle Largest Empty Circles Closest Point Pair Farthest Point Pair
Closest Vertex Circle Covering Visibility Polygon / Isovist
Bin Pack Rectangle Bin Pack
Hilbert Sort Faces

Circle Packing

Front Chain Trinscribed
Maximum Inscribed Stochastic
Repulsion Square Lattice
Hex Lattice Tangency Pack
Obstacle

Coloring

Construction

Supercircle Supershape Star
Random Convex Polygon Heart Ring Arc
Linear Spiral Fermat Spiral Rectangular Spiral Hilbert Curve
Sierpinski Carpet Sierpinski Curve Sierpinski Tri-Curve (TRI) Sierpinski Tri-Curve (TETRA)
Koch Snowflake Blobbie RSFC Taijitu
Arbelos Teardrop Sponge
Gear Super Random Polygon Random Bezier Polygon

Point Sets

Random Gaussian Square Grid Hex Grid
Phyllotaxis Poisson Hexagon Ring
Halton LDS Hammersley LDS Plastic LDS Jittered Plastic LDS
Sobol LDS N-Rooks LDS Distance Prune Hilbert Sort
EMST Cluster Weighted Median

Segment Sets

Graph-matched Stochastic Noded
Parallel Polygon Interior Segments

Tiling & Subdivision

Random Quad Subdivision Random Rect Subdivision Random Triangle Subdivision Hatch Subdivision
Islamic Tiling Doyle Spiral Hexagon Tiling
Penrose Tiling Square-Triangle Tiling

pgs's People

Contributors

dependabot-preview[bot] avatar dependabot[bot] avatar imgbotapp avatar micycle1 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

pgs's Issues

Examples using the 'Illustrations'

Hi, in the 'Illustrations' part in the README.MD file there are many examples. I think this examples are obtained using the library. Why not expand the examples library with the code used to get the images shown? I think this could be very useful for the people approaching the library,

please expose `PGS_Contour.offsetCurves(...)` method

when working with offsets for CNC paths generation, I feel greatly limited with two existing methods: PGS_Contour.offsetCurvesInwards and PGS_Contour.offsetCurvesOutwards. First one generates uncontrollable number of offsets, and it's impossible to know if any subsequent offset consists of multiple children or not (I just get outlines for subsequent steps, together with their children in one set, unable to differentiate them).
The other method provides control on number of curves to offset, so I can potentially generate them one by one, but works only outside :-) no way to cheat it, since it only accepts positive offset distances.
The only way to control it fully would be to use underlying (invisible) method PGS_Contour.offsetCurves(...) but it is currently private - please either expose it, or add another method that gives more control.

`PShape.draw(PGraphics)` not working with shapes created by PGS

Hi

Lovely library! Seems to work great when using it the default Processing way in draw().

However in my setup I maintan a stage where I can manage all the PShapes in the scene and draw them with their shape.draw(PGraphics) method (I'm passing the PApplet.g PGraphics to it).

This works great when I create shapes with createShape(), but when using methods from PGS I can't get the shapes to show at all.

I suspect - although it's really just a guess - it's since PGS creates new shapes with new PShape() and not createShape() - the latter sets the internal protected PGraphics g in the PShape - the constructor of PShape does not.

Or perhaps I'm way off.

Any thoughts on how I could investigate this further - or perhaps even a way to overcome it?

All the best, Thomas

Shape loses its filling with successive subtracts

Hello,

Your library is (almost) a life savior for me, thanks!

I have an issue with a shape that I want to create. I want so subtract several rectangles from a circle, like so:

import micycle.pgs.*;

void setup() {
  background(255);
  size(800, 600);
  smooth();
}

void draw() {
  fill(#505050);
  noStroke();
  translate(400, 300);
 
  // create a donut
  var outer = createShape(ELLIPSE, 0, 0, 200, 200);
  var inner = createShape(ELLIPSE, 0, 0, 100, 100);
  outer = PGS_ShapeBoolean.subtract(outer, inner);
  
  // display on left side
  shape(outer, -250, 0);
  
  // make a first hole
  var hole1 = createShape(RECT, 0, -20, 200, 40);
  outer = PGS_ShapeBoolean.subtract(outer,hole1);
  
  // display in the center
  shape(outer);

  // make a second hole
  var hole2 = createShape(RECT, 0, -20, 200, 40);
  hole2.rotate(PI/3);
  outer = PGS_ShapeBoolean.subtract(outer,hole2);
  
  // display on right side
  shape(outer, 250, 0);
}

image

I would expect the result to be the same as the second shape + one more hole, but it loses its color.
Is there a limitation in subtractions, or did I discover a bug?

Thank you!

`PGS_Processing.slice()` returns nullpointer exception in `P2D` render mode

Not sure if this is an issue, but I ran into a nullpointer exception when I was trying to slice a custom PShape using the P2D renderer.
PShapes created in this renderer are for some reason of the type PShapeOpenGL which I think PGS can't handle, right?. Leaving the renderer option blank results in no errors.

Intermittent "Invalid number of points in LinearRing" when using `PGS_ShapeBoolean.subtract()`

Hi @micycle1, I'm using PGS to do hidden line removal for my old Roland plotter. The idea is that because the plotter has no concept of .fill(), I'm progressively subtracting / merging shapes from each other.

It seems to work for the most part, but I intermittently get an illegal arg exception - Invalid number of points in LinearRing (found 2 - must be 0 or >= 4) when calling PGS_ShapeBoolean.subtract()

I've tried to mock this up in the below code - it will stop at the offending PShape and draw in pink. All the 'valid' PShapes above that one will be drawn in black.

Hoping for some pointers please, maybe I'm misusing the subtract / shape group ? Apologies in advance, I'm new to both Java & Processing!

subtract

import micycle.pgs.*;

void setup() 
{
  size(3000, 1800);
}

void draw()
{  
  noLoop();
  ArrayList<RandomPoly> polys = new ArrayList<RandomPoly>();
  int max = 20;

  //create objects, randomly placed over each other
  for (int i = 0; i < max; i++)
  {
    boolean intersectsPrevious = false;
    while (!intersectsPrevious)
    {
      RandomPoly p = new RandomPoly();

      if (i == 0)
        intersectsPrevious = true;
      else 
      intersectsPrevious = PGS_ShapePredicates.intersect(polys.get(i - 1).shape, p.shape);

      if (intersectsPrevious)
      {
        polys.add(p);
      }
    }
  }

  //now plot them in reverse order
  PShape group = polys.get(polys.size() - 1).shape;
  for (int i = polys.size() - 2; i >= 0; i--)
  {
    RandomPoly background = polys.get(i);
    PShape merged = mergeShapes(background.shape, group);

    if (merged == null)
    {
      shape(background.shape); //draw invalid shape in pink and stop
      break;
    } else
    {
      group = merged;
    }
  }

  PGS_Conversion.setAllStrokeColor(group, color(0), 1);
  shape(group);
}

//Here we are taking a background and foreground shape, and making a group of out of 
// 1 - the foreground shape, and 
// 2 - the subtraction of foreground from background
//This allows us to send to a plotter that has no concept of fill() 
PShape mergeShapes(PShape backgroundShape, PShape foregroundShape)
{
  PShape g = createShape(GROUP);

  g.addChild(foregroundShape);
  try
  {
    g.addChild(PGS_ShapeBoolean.subtract(backgroundShape, foregroundShape));
  }
  catch(Exception e) //java.lang.IllegalArgumentException: Invalid number of points in LinearRing (found 2 - must be 0 or >= 4)
  {
    print(e);
    return null;
  }

  return g;
}

class RandomPoly
{
  PShape shape;
  PVector pos;

  RandomPoly()
  {
    float xStart = randomGaussian() * 200 + width / 2;
    float yStart = randomGaussian() * 200 + height / 2;

    pos = new PVector(xStart, yStart);
    shape = PGS_Transformation.translate(
      PGS_Construction.createRandomPolygon(4, width / 4, height / 4), 
      pos.x, 
      pos.y);
  }
}

Conversion: handle multi-contour/shape PShapes

In converting from PShapes to Geometries, it was assumed until now that in shapes having multiple contours, every contour beyond the first must represent a hole.

Here's one counter-example to this assumption, where each band of the letter is not a child shape, but a contour:

image

To convert such shapes properly the code must check the winding of each contour: if it winds in the opposing (usually counter-clockwise) direction to the first contour, it represents a hole; if it winds in the same direction as the first contour, it represents another shape feature and should be preserved.

Readme request: link gifs to source code of each

Hi! Amazing collection of algorithms!! :)

An idea: I was thinking that it would be very nice if when clicking on one of the gifs or pngs it would jump to the source code of the program that created it (instead of linking to the original image file).

Otherwise one may see something they would like to play with, but how to find the related code?

Cheers!

Not working with `P2D`

When I used with P2D mode. I've got always a NullPointerException that block the script.

`PGS_ShapeBoolean.union(PShape, PShape)` returns shape identical to input argument

Hi,

i have an array of many PShapes created from tiling an initial square repeatedly using PGS_Processing.slice(). Within that array i pick two neigbouring shapes for unision via the PGS_ShapeBoolean.union(PShape,PShape) function. This works like a charm most of the time and returns a PShape that combines the areas of the two input shapes. Sometimes it doesen't want to do so and instead just returns a PShape that is identical to the second input argument of union(PShape,PShape).

What's confusing is that i cannot tell the difference between cases where it works and where it doesnt. The input shapes look valid to me in both cases...

Not shure if this is a bug or if you can point me towards common issues with unision that i should look into...

Thx for a reply and thanks for sharing this awesome library!

Expected a different result from `PGS_ShapeBoolean.union()`

Hi Micycle,

This seems like a great library thanks! I was testing the boolean functionality with two simples shapes an ellipse and a rectangle but it didn't gave me the result I was expecting. It seems the PShapes change positions when united with each other? The expected behaviour would be a unified shape at the same position I'd say. Thought?

import micycle.pgs.*;

void setup() {
 size(595, 842, P2D);
}

void draw() {
  background(0);

  PShape shapeOne = createShape(ELLIPSE, 100, 100, width * 0.4, width * 0.4);
  shapeOne.setFill(#ffff00);

  PShape shapeTwo = createShape(RECT, 150, 150, width * 0.5, width * 0.5);
  shapeTwo.setFill(#00ff00);

  shape(shapeOne);
  shape(shapeTwo);

  PShape union = PGS_ShapeBoolean.union(shapeOne, shapeTwo);
  union.setFill(#ff0000);
  translate(0, 300);
  shape(union);

}

In yellow and green the source shapes. In red the unified shape, slightly translated on the y-axis.

Screenshot 2022-01-04 at 19 07 12

The function `shapeIntersections(PShape, PShape)` does not exist.

hi, thanks again for this library
two examples show errors:
voronoiCutOut line 68: The function shapeIntersections(PShape, PShape) does not exist.
intersectionsBoids line 32: The function lineSegmentIntersections(List) does not exist.

all others works well here (macos big sur -M1)

i think i will spend a lot of time with this (;
i let you know if see something else
thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.