Package micycle.pgs

Class PGS_Morphology

java.lang.Object
micycle.pgs.PGS_Morphology

public final class PGS_Morphology extends Object
Methods that affect the geometry or topology of shapes.
Author:
Michael Carleton
  • Method Summary

    Modifier and Type
    Method
    Description
    static processing.core.PShape
    buffer(processing.core.PShape shape, double buffer)
    Computes a rounded buffer area around the shape, having the given buffer width.
    static processing.core.PShape
    buffer(processing.core.PShape shape, double buffer, PGS_Contour.OffsetStyle bufferStyle)
    Computes a buffer area around the shape, having the given buffer width and buffer style (either round, miter, bevel).
    static processing.core.PShape
    chaikinCut(processing.core.PShape shape, double ratio, int iterations)
    Smoothes a shape by recursively cutting its corners, a technique introduced by George Chaikin in 1974.
    static processing.core.PShape
    dilationErosion(processing.core.PShape shape, double buffer)
    Applies a positive followed by a negative buffer (in a single operation), the effect of which is small holes and gaps are filled in, while the general structure of the shape is preserved.
    static processing.core.PShape
    erosionDilation(processing.core.PShape shape, double buffer)
    Applies a negative followed by a positive buffer (in a single operation), the effect of which is small edges/islands are removed, while the general structure of the shape is preserved.
    static processing.core.PShape
    fieldWarp(processing.core.PShape shape, double magnitude, double noiseScale, boolean densify)
    Warps/perturbs a shape by displacing vertices according to a 2D noise vector field.
    static processing.core.PShape
    fieldWarp(processing.core.PShape shape, double magnitude, double noiseScale, double time, boolean densify, long noiseSeed)
    Warps/perturbs a shape by displacing vertices according to a 2D noise vector field.
    static processing.core.PShape
    interpolate(processing.core.PShape from, processing.core.PShape to, double interpolationFactor)
    Generates an intermediate shape between two shapes by interpolating between them.
    static processing.core.PShape
    interpolate(processing.core.PShape from, processing.core.PShape to, int frames)
    Generates intermediate shapes (frames) between two shapes by interpolating between them.
    static processing.core.PShape
    minkDifference(processing.core.PShape source, processing.core.PShape subtract)
    Computes a Minkowski difference (a.k.a erosion) of the two source shapes.
    static processing.core.PShape
    minkSum(processing.core.PShape source, processing.core.PShape addition)
    Computes a Minkowski sum (a.k.a dilation) of the two source shapes.
    static processing.core.PShape
    pinchWarp(processing.core.PShape shape, processing.core.PVector pinchPoint, double weight)
    Applies a pinch warping effect to a shape, distorting vertices towards a specified point.
    static processing.core.PShape
    radialWarp(processing.core.PShape shape, double magnitude, double warpOffset, boolean densify)
    Distorts a polygonal shape by radially displacing its vertices along the line connecting each vertex with the shape's centroid, creating a warping or perturbing effect.
    static processing.core.PShape
    reducePrecision(processing.core.PShape shape, double precision)
    Reduces the precision of a shape, whilst ensuring the output shape is valid.
    static processing.core.PShape
    round(processing.core.PShape shape, double extent)
    Modifies the corners of a specified shape by replacing each angular corner with a smooth, circular arc.
    static processing.core.PShape
    simplify(processing.core.PShape shape, double distanceTolerance)
    Simplifies a shape using the Douglas-Peucker algorithm, reducing the complexity and number of vertices of the shape.
    static processing.core.PShape
    simplifyDCE(processing.core.PShape shape, DiscreteCurveEvolution.DCETerminationCallback terminationCallback)
    Simplifies a shape via Discrete Curve Evolution.
    static processing.core.PShape
    simplifyHobby(processing.core.PShape shape, double tension)
    Creates a Hobby Curve from the vertices of the shape.
    static processing.core.PShape
    simplifyTopology(processing.core.PShape shape, double distanceTolerance)
    Simplifies a shape, whilst preserving the topological structure of the shape (holes, etc.).
    static processing.core.PShape
    simplifyVW(processing.core.PShape shape, double distanceTolerance)
    Simplifies a shape using the Visvalingam-Whyatt area-based algorithm, reducing the complexity and number of vertices of the shape.
    static processing.core.PShape
    sineWarp(processing.core.PShape shape, double magnitude, double frequency, double phase)
    Warps/perturbs a shape by displacing vertices (both positively and negatively) according to the magnitude of a sine wave which follows the shape perimeter at some frequency.
    static processing.core.PShape
    smooth(processing.core.PShape shape, double alpha)
    Smoothes a shape.
    static processing.core.PShape
    smoothEllipticFourier(processing.core.PShape shape, int descriptors)
    Calculates the Elliptic Fourier Descriptors (EFD) of a specified shape, yielding a simplified/smoothed shape representation based on the specified number of descriptors.
    static processing.core.PShape
    smoothGaussian(processing.core.PShape shape, double sigma)
    Smoothes a shape by applying a gaussian filter to vertex coordinates.
    static processing.core.PShape
    variableBuffer(processing.core.PShape shape, double startDistance, double endDistance)
    Buffers a shape with a varying buffer distance (interpolated between a start distance and an end distance) along the shape's perimeter.
    static processing.core.PShape
    variableBuffer(processing.core.PShape shape, BiFunction<org.locationtech.jts.geom.Coordinate,Double,Double> bufferCallback)
    Applies a variable buffer to a shape.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Method Details

    • buffer

      public static processing.core.PShape buffer(processing.core.PShape shape, double buffer)
      Computes a rounded buffer area around the shape, having the given buffer width.
      Parameters:
      shape -
      buffer - extent/width of the buffer (which may be positive or negative)
      Returns:
      a polygonal shape representing the buffer region (which may be empty)
      See Also:
    • buffer

      public static processing.core.PShape buffer(processing.core.PShape shape, double buffer, PGS_Contour.OffsetStyle bufferStyle)
      Computes a buffer area around the shape, having the given buffer width and buffer style (either round, miter, bevel).
      Parameters:
      shape -
      buffer - extent/width of the buffer (which may be positive or negative)
      Returns:
      a polygonal shape representing the buffer region (which may be empty)
      Since:
      1.3.0
      See Also:
    • variableBuffer

      public static processing.core.PShape variableBuffer(processing.core.PShape shape, double startDistance, double endDistance)
      Buffers a shape with a varying buffer distance (interpolated between a start distance and an end distance) along the shape's perimeter.
      Parameters:
      shape - a single polygon or lineal shape
      startDistance - the starting buffer amount
      endDistance - the terminating buffer amount
      Returns:
      a polygonal shape representing the variable buffer region (which may be empty)
      Since:
      1.3.0
    • variableBuffer

      public static processing.core.PShape variableBuffer(processing.core.PShape shape, BiFunction<org.locationtech.jts.geom.Coordinate,Double,Double> bufferCallback)
      Applies a variable buffer to a shape. The buffer width at each vertex is determined by a callback function that considers the vertex's properties and its relative position along the shape's boundary.

      Example usage:

       
       PShape bufferedShape = bufferWithCallback(inputShape, (coordinate, fraction) -> {
       	// Example logic: buffer width decreases linearly from 10 units at the
       	// start to 1 unit at the end
       	return 10 - (fraction * (10 - 1));
       });
       
       
      Parameters:
      shape - A single polygon or lineal shape
      bufferCallback - A callback function that receives the vertex coordinate and a double representing tractional distance (0...1) of the vertex along the shape's boundary. The function may use properties of the vertex, or its position, to determine the buffer width at that point.
      Returns:
      A new shape representing the original shape buffered with variable widths as specified by the callback function. The width at each vertex is calculated independently.
      Since:
      2.0
    • erosionDilation

      public static processing.core.PShape erosionDilation(processing.core.PShape shape, double buffer)
      Applies a negative followed by a positive buffer (in a single operation), the effect of which is small edges/islands are removed, while the general structure of the shape is preserved.

      This operation is known as "opening" in computer vision.

      Parameters:
      shape - polygonal shape
      buffer - a positive number
      Returns:
      See Also:
    • dilationErosion

      public static processing.core.PShape dilationErosion(processing.core.PShape shape, double buffer)
      Applies a positive followed by a negative buffer (in a single operation), the effect of which is small holes and gaps are filled in, while the general structure of the shape is preserved.

      This operation is known as "closing" in computer vision.

      Parameters:
      shape - polygonal shape
      buffer - a positive number
      Returns:
      Since:
      1.3.0
      See Also:
    • simplify

      public static processing.core.PShape simplify(processing.core.PShape shape, double distanceTolerance)
      Simplifies a shape using the Douglas-Peucker algorithm, reducing the complexity and number of vertices of the shape.

      During the process shapes can be split, collapse to lines or disappear. Holes can be created or disappear.

      Parameters:
      shape -
      distanceTolerance - the tolerance to use
      Returns:
      simplifed copy of the shape
      See Also:
    • simplifyVW

      public static processing.core.PShape simplifyVW(processing.core.PShape shape, double distanceTolerance)
      Simplifies a shape using the Visvalingam-Whyatt area-based algorithm, reducing the complexity and number of vertices of the shape.
      Parameters:
      shape -
      distanceTolerance - The simplification tolerance is specified as a distance.This is converted to an area tolerance by squaring it.
      Returns:
      simplifed copy of the shape
      See Also:
    • simplifyTopology

      public static processing.core.PShape simplifyTopology(processing.core.PShape shape, double distanceTolerance)
      Simplifies a shape, whilst preserving the topological structure of the shape (holes, etc.).
      Parameters:
      shape -
      distanceTolerance - the tolerance to use
      Returns:
      simplifed copy of the shape
      See Also:
    • simplifyDCE

      public static processing.core.PShape simplifyDCE(processing.core.PShape shape, DiscreteCurveEvolution.DCETerminationCallback terminationCallback)
      Simplifies a shape via Discrete Curve Evolution.

      This algorithm simplifies a shape by iteratively removing kinks from the shape, starting with those having the least shape-relevance.

      The simplification process terminates according to a user-specified callback that decides whether the DCE algorithm should terminate based on the current kink (having a candidate vertex), using its coordinates, relevance score, and the number of vertices remaining in the simplified geometry. Implementations can use this method to provide custom termination logic which may depend on various factors, such as a threshold relevance score, a specific number of vertices to preserve, or other criteria.

      Note: the termination callback is applied per ring (boundary, hole, line, etc) in the input.

      Parameters:
      shape - The input shape to be simplified, which can be a polygonal (inclusive of holes) or a lineal shape. GROUP shapes are supported.
      terminationCallback - The callback used to determine when the simplification process should terminate. true if the DCE process should terminate; false otherwise.
      Returns:
      A new, simplified copy of the input shape, with the least significant kinks or vertices removed according to the provided fraction.
      Since:
      2.0
    • simplifyHobby

      public static processing.core.PShape simplifyHobby(processing.core.PShape shape, double tension)
      Creates a Hobby Curve from the vertices of the shape. This tends to simplify/round the geometry of shape, but may actually increase the number of vertices due to increased curvature.

      You may want to consider simplifying a shape (reducing vertex count) with other methods before applying Hobby simplification.

      Parameters:
      shape - vertices to use as basis for the Hobby Curve
      tension - a parameter that controls the tension of the curve (how tightly it is "pulled" towards underlying vertices). Suitable domain is [0.666...3].
      Returns:
      a Hobby Curve
      Since:
      1.4.0
    • minkSum

      public static processing.core.PShape minkSum(processing.core.PShape source, processing.core.PShape addition)
      Computes a Minkowski sum (a.k.a dilation) of the two source shapes. The addition shape should probably be centered on (0,0) for best results.

      To instill you with intuition of what a Minkowski sum looks like, here are a few examples:

      • The sum of any shape and a point is that shape translated by that point.
      • The sum of any shape and two points is two translated (possibly overlapping) copies of that shape.
      • The sum of two circles is a larger circle (sum the radii) with its centre at the sum of the centres of the smaller circles.
      • The sum of any shape and a line is that shape swept through that line. Think of placing your shape in sand, and dragging it along the line.
      • Similarly, the sum of a shape and any curve is what you’d get by sweeping the shape through the curve.
      • The sum of two parallel lines is a longer line.
      • For perpendicular lines, you get a square.
      Returns:
      shape representing the Minkowski sum of source+addition
      See Also:
    • minkDifference

      public static processing.core.PShape minkDifference(processing.core.PShape source, processing.core.PShape subtract)
      Computes a Minkowski difference (a.k.a erosion) of the two source shapes. The subtract shape should probably be centered on (0,0) for best results.
      Returns:
      shape representing the Minkowski difference of source-subtract
      See Also:
    • smooth

      public static processing.core.PShape smooth(processing.core.PShape shape, double alpha)
      Smoothes a shape. The smoothing algorithm inserts new vertices which are positioned using Bezier splines. The output shape tends to be a little larger than the input.
      Parameters:
      shape - shape to smooth
      alpha - curvedness parameter (0 is linear, 1 is round, >1 is increasingly curved)
      Returns:
      smoothed copy of the shape
      See Also:
    • smoothGaussian

      public static processing.core.PShape smoothGaussian(processing.core.PShape shape, double sigma)
      Smoothes a shape by applying a gaussian filter to vertex coordinates. At larger values, this morphs the input shape much more visually than smooth().
      Parameters:
      shape - the shape to smooth
      sigma - The standard deviation of the gaussian kernel. Larger values provide more smoothing.
      Returns:
      smoothed copy of the shape
      See Also:
    • smoothEllipticFourier

      public static processing.core.PShape smoothEllipticFourier(processing.core.PShape shape, int descriptors)
      Calculates the Elliptic Fourier Descriptors (EFD) of a specified shape, yielding a simplified/smoothed shape representation based on the specified number of descriptors.

      The EFD technique is an approach for shape analysis and simplification that decomposes a shape into a sequence of elliptic harmonic components. These components encapsulate the contour details of the shape: lower-order harmonics capture the broad geometry of the shape, while higher-order harmonics register the detailed, high-frequency contour characteristics, analogous to Principal Component Analysis (PCA). This technique is particularly effective for generating condensed or smoother versions of complex shapes.

      Parameters:
      shape - A polygonal shape to be transformed using the EFD.
      descriptors - The desired level of the EFD, denoting the quantity of harmonics to be retained in the output. The maximum value is half the total number of vertices in the shape, while the minimum allowable value is 2. As the number of harmonics is increased, the output tends towards the input shape.
      Returns:
      A new PShape, simplified through the application of the Elliptic Fourier Descriptors up to the indicated order. This shape will always have the same number of vertices as the original.
      Since:
      1.4.0
    • round

      public static processing.core.PShape round(processing.core.PShape shape, double extent)
      Modifies the corners of a specified shape by replacing each angular corner with a smooth, circular arc. The radius of each arc is determined proportionally to the shorter of the two lines forming the corner.
      Parameters:
      shape - The original PShape object whose corners are to be rounded.
      extent - Specifies the degree of corner rounding, with a range from 0 to 1. A value of 0 corresponds to no rounding, whereas a value of 1 yields maximum rounding while still maintaining the validity of the shape. Values above 1 are accepted but may produce unpredictable results.
      Returns:
      A new PShape object with corners rounded to the specified extent.
    • chaikinCut

      public static processing.core.PShape chaikinCut(processing.core.PShape shape, double ratio, int iterations)
      Smoothes a shape by recursively cutting its corners, a technique introduced by George Chaikin in 1974.

      This method can be used to generate smooth-looking curves from a limited number of points. More iterations result in more smoothing.

      Parameters:
      shape - The shape to be smoothed
      ratio - A ratio (between 0 and 1) determining how far along each edge to perform the two cuts. For example, a ratio of 0.5 will cut the underlying edge twice, at 0.25x and 0.75x along its length. A value of 1 will cut each edge once, directly at its midpoint. It is recommended to use a value of 0.5 for this parameter.
      iterations - The number of cutting iterations/recursions to perform. A value of 1 will simply cut the corners once, higher values will effectively smooth the cut. Values greater than ~10 generally have no additional visual effect.
      Returns:
      A copy of the input shape with corners cut.
      Since:
      1.1.0
    • radialWarp

      public static processing.core.PShape radialWarp(processing.core.PShape shape, double magnitude, double warpOffset, boolean densify)
      Distorts a polygonal shape by radially displacing its vertices along the line connecting each vertex with the shape's centroid, creating a warping or perturbing effect.

      The shape's input vertices can optionally be densified prior to the warping operation.

      Parameters:
      shape - A polygonal PShape object to be distorted.
      magnitude - The degree of the displacement, which determines the maximum Euclidean distance a vertex will be moved in relation to the shape's centroid.
      warpOffset - An offset angle, which establishes the starting angle for the displacement process.
      densify - A boolean parameter determining whether the shape should be densified (by inserting additional vertices at a distance of 1) before warping. If true, shapes with long edges will experience warping along their entire length, not just at the original vertices.
      Returns:
      A new PShape object that has been radially warped according to the specified parameters.
    • sineWarp

      public static processing.core.PShape sineWarp(processing.core.PShape shape, double magnitude, double frequency, double phase)
      Warps/perturbs a shape by displacing vertices (both positively and negatively) according to the magnitude of a sine wave which follows the shape perimeter at some frequency.
      Parameters:
      shape - single polygonal shape
      magnitude - maximum perpendicular displacement along the shape perimeter
      frequency - sine wave frequency. Values less than 1 will result in an offset that does not smoothly join up.
      phase - sine wave phase. corresponds to the fraction (0...1) around the shape perimeter where the wave starts (0 displacement).
      Returns:
      warped polygonal shape
      Since:
      1.3.0
    • fieldWarp

      public static processing.core.PShape fieldWarp(processing.core.PShape shape, double magnitude, double noiseScale, boolean densify)
      Warps/perturbs a shape by displacing vertices according to a 2D noise vector field.

      Inputs may be densified before warping.

      Parameters:
      shape - a polygonal shape
      magnitude - magnitude of the displacement (acting as noise value multiplier). The value defines the maximum displacement of a vertex in the both x and y axes.
      noiseScale - the scale of the 2D noise vector field. This affects how of the coarseness of warping. Smaller values (~0.2) lead to more fine warping (at edges), whereas larger values (~2) affect the shape geometry at a larger scale.
      densify - whether to densify the shape (using distance=1) before warping. When true, shapes with long edges will undergo warping along the whole edge (rather than only at the original vertices).
      Returns:
      warped polygonal shape
      See Also:
    • fieldWarp

      public static processing.core.PShape fieldWarp(processing.core.PShape shape, double magnitude, double noiseScale, double time, boolean densify, long noiseSeed)
      Warps/perturbs a shape by displacing vertices according to a 2D noise vector field.

      Inputs may be densified before warping for more finely-grained warping.

      Parameters:
      shape - a polygonal shape
      magnitude - magnitude of the displacement (acting as noise value multiplier). The value defines the maximum displacement of a vertex in the both x and y axes.
      noiseScale - the scale of the 2D noise vector field. This affects how of the coarseness of warping. Smaller values (~0.2) lead to more fine warping (at edges), whereas larger values (~2) affect the shape geometry at a larger scale.
      time - used to offset the underlying noise field and hence animate the warping over time
      densify - whether to densify the shape (using distance=1) before warping. When true, shapes with long edges will undergo warping along the whole edge (rather than only at the original vertices).
      noiseSeed - a seed to pass to the underlying noise generator
      Returns:
      warped polygonal shape
      See Also:
    • pinchWarp

      public static processing.core.PShape pinchWarp(processing.core.PShape shape, processing.core.PVector pinchPoint, double weight)
      Applies a pinch warping effect to a shape, distorting vertices towards a specified point. The strength of the pinch effect decreases with distance from the pinch point, creating a localized warping effect.
      Parameters:
      shape - The shape. The original shape is not modified; instead, a new warped shape is returned.
      pinchPoint - The point in 2D space towards which the shape will be pinched. Vertices closer to this point will be affected more strongly.
      weight - The strength of the pinching effect. Higher values create stronger distortion.
      Returns:
      A new PShape object comprising the warped geometry.
      Since:
      2.0
    • interpolate

      public static processing.core.PShape interpolate(processing.core.PShape from, processing.core.PShape to, double interpolationFactor)
      Generates an intermediate shape between two shapes by interpolating between them. This process has many names: shape morphing / blending / averaging / tweening / interpolation.

      The underlying technique rotates one of the shapes to minimise the total distance between each shape's vertices, then performs linear interpolation between vertices. This performs well in practice but the outcome worsens as shapes become more concave; more sophisticated techniques would employ some level of rigidity preservation.

      Parameters:
      from - a single polygon; the shape we want to morph from
      to - a single polygon; the shape we want to morph from into
      interpolationFactor - between 0...1
      Returns:
      a polygonal PShape
      Since:
      1.2.0
      See Also:
    • interpolate

      public static processing.core.PShape interpolate(processing.core.PShape from, processing.core.PShape to, int frames)
      Generates intermediate shapes (frames) between two shapes by interpolating between them. This process has many names: shape morphing / blending / averaging / tweening / interpolation.

      This method is faster than calling interpolate() repeatedly for different interpolation factors.

      Parameters:
      from - a single polygon; the shape we want to morph from
      to - a single polygon; the shape we want to morph from into
      frames - the number of frames (including first and last) to generate. >= 2
      Returns:
      a GROUP PShape, where each child shape is a frame from the interpolation
      Since:
      1.3.0
      See Also:
    • reducePrecision

      public static processing.core.PShape reducePrecision(processing.core.PShape shape, double precision)
      Reduces the precision of a shape, whilst ensuring the output shape is valid.

      This method effectively rounds vertices to the nearest value given by precision.

      Parameters:
      shape - shape to reduce
      precision - the exact grid size with which to round shape vertices. should be non-zero and positive
      Returns:
      reduced copy of input
      Since:
      1.3.0