Package micycle.pgs

Class PGS_Tiling

java.lang.Object
micycle.pgs.PGS_Tiling

public final class PGS_Tiling extends Object
Tiling, tessellation and subdivision of the plane using periodic or non-periodic geometric shapes.

A tiling is created when a collection of tiles fills a plane such that no gaps occur between the tiles and no two tiles overlap each other.

Naming convention in this class:
Methods ending with "subdivision" recursively break the plane down into smaller and smaller shapes, usually of the same geometric type at each step (for example, rectangles are split into smaller rectangles).
Methods ending with "division" split the plane all at once, in a single step, often by making several cuts or slices, with no recursion.

Since:
1.2.0
Author:
Michael Carleton
  • Method Summary

    Modifier and Type
    Method
    Description
    static processing.core.PShape
    annularBricks(int nRings, double cx, double cy, double innerRadius, double ringGrowth, double segGrowth)
    Generates a geometric arrangement composed of annular-sector bricks arranged in concentric circular rings.
    static processing.core.PShape
    arcDivision(double width, double height, int arcs, long seed)
    Creates a cellular partition of the plane using arcs formed by circles seeded along its boundary.
    static processing.core.PShape
    auxeticTiling(double width, double height, double cellSize, int A, int B, int C)
    Builds a tiling of interlocking cells that form an auxetic structure.
    static processing.core.PShape
    aztecDiamond(double originX, double originY, int order, double cellSize, long seed)
    Produces a random domino tiling of the Aztec diamond of the given order.
    static List<processing.core.PVector>
    doyleSpiral(double centerX, double centerY, int p, int q, double maxRadius)
    Generates a Doyle spiral.
    static processing.core.PShape
    hatchSubdivision(double width, double height, int gridCountX, int gridCountY, long seed)
    Randomly subdivides the plane into equal-width strips having varying lengths.
    static processing.core.PShape
    hexTiling(double width, double height, double sideLength, boolean flat)
    Generates a hexagonal tiling of the plane.
    static processing.core.PShape
    islamicTiling(double width, double height, double w, double h)
    Generates an "islamic-style" (Girih) tiling of the plane.
    static processing.core.PShape
    penroseTiling(double centerX, double centerY, double radius, int steps)
    Generates a Penrose Tiling (consisting of rhombi).
    static processing.core.PShape
    quadSubdivision(double width, double height, int depth)
    Recursively and randomly subdivides the given/bounded plane into convex quad polygons.
    static processing.core.PShape
    quadSubdivision(double width, double height, int depth, long seed)
    Recursively and randomly subdivides the given/bounded plane into convex quad polygons.
    static processing.core.PShape
    rectSubdivision(double width, double height, int maxDepth)
    Recursively and randomly subdivides the given/bounded plane into rectangles.
    static processing.core.PShape
    rectSubdivision(double width, double height, int maxDepth, long seed)
    Recursively and randomly subdivides the given/bounded plane into rectangles.
    static processing.core.PShape
    sliceDivision(double width, double height, int slices, boolean forceOpposite, long seed)
    Divides the plane into randomly “sliced” polygonal regions.
    static processing.core.PShape
    softCells(processing.core.PShape mesh, double ratio, micycle.pgs.commons.SoftCells.TangentMode mode, long seed)
    Generates a softened (curved) version of a tiling using the SoftCells edge-bending algorithm.
    static processing.core.PShape
    squareGrid(double width, double height, double cellSize)
    Divides the plane into a simple axis-aligned grid using square cells.
    static processing.core.PShape
    squareTriangleTiling(double width, double height, double tileSize)
    Generates a non-periodic tiling, comprising squares and equilateral triangles.
    static processing.core.PShape
    squareTriangleTiling(double width, double height, double tileSize, long seed)
    Generates a non-periodic tiling, comprising squares and equilateral triangles, having a given seed.
    static processing.core.PShape
    triangleSubdivision(double width, double height, int maxDepth)
    Recursively and randomly subdivides the given/bounded plane into triangles.
    static processing.core.PShape
    triangleSubdivision(double width, double height, int maxDepth, long seed)
    Recursively and randomly subdivides the given/bounded plane into triangles.

    Methods inherited from class java.lang.Object

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

    • rectSubdivision

      public static processing.core.PShape rectSubdivision(double width, double height, int maxDepth)
      Recursively and randomly subdivides the given/bounded plane into rectangles.
      Parameters:
      width - width of the quad subdivision plane
      height - height of the quad subdivision plane
      maxDepth - maximum number of subdivisions (recursion depth)
      Returns:
      a GROUP PShape, where each child shape is a face of the subdivision
      See Also:
    • rectSubdivision

      public static processing.core.PShape rectSubdivision(double width, double height, int maxDepth, long seed)
      Recursively and randomly subdivides the given/bounded plane into rectangles.
      Parameters:
      width - width of the quad subdivision plane
      height - height of the quad subdivision plane
      maxDepth - maximum number of subdivisions (recursion depth)
      seed - the random seed
      Returns:
      a GROUP PShape, where each child shape is a face of the subdivision
      See Also:
    • triangleSubdivision

      public static processing.core.PShape triangleSubdivision(double width, double height, int maxDepth)
      Recursively and randomly subdivides the given/bounded plane into triangles.
      Parameters:
      width - width of the subdivision plane
      height - height of the subdivision plane
      maxDepth - maximum number of subdivisions (recursion depth)
      Returns:
      a GROUP PShape, where each child shape is a face of the subdivision
      See Also:
    • triangleSubdivision

      public static processing.core.PShape triangleSubdivision(double width, double height, int maxDepth, long seed)
      Recursively and randomly subdivides the given/bounded plane into triangles.
      Parameters:
      width - width of the subdivision plane
      height - height of the subdivision plane
      maxDepth - maximum number of subdivisions (recursion depth)
      seed - the random seed
      Returns:
      a GROUP PShape, where each child shape is a face of the subdivision
      See Also:
    • quadSubdivision

      public static processing.core.PShape quadSubdivision(double width, double height, int depth)
      Recursively and randomly subdivides the given/bounded plane into convex quad polygons.
      Parameters:
      width - width of the plane that is subdivided
      height - height of the plane that is subdivided
      depth - number of subdivisions (recursion depth)
      Returns:
      a GROUP PShape, where each child shape is a face of the subdivision
      See Also:
    • quadSubdivision

      public static processing.core.PShape quadSubdivision(double width, double height, int depth, long seed)
      Recursively and randomly subdivides the given/bounded plane into convex quad polygons.
      Parameters:
      width - width of the quad subdivision plane
      height - height of the quad subdivision plane
      depth - number of subdivisions (recursion depth)
      seed - the random seed
      Returns:
      a GROUP PShape, where each child shape is a face of the subdivision
      See Also:
    • squareGrid

      public static processing.core.PShape squareGrid(double width, double height, double cellSize)
      Divides the plane into a simple axis-aligned grid using square cells.

      Grid lines are placed every cellSize units in X and Y. If width or height are not exact multiples of cellSize, the last row/col will be a smaller “remainder” cell band.

      Parameters:
      width - the width of the plane
      height - the height of the plane
      cellSize - the desired square cell size (must be > 0)
      Returns:
      a GROUP PShape containing the grid cells
      Since:
      2.2
    • hatchSubdivision

      public static processing.core.PShape hatchSubdivision(double width, double height, int gridCountX, int gridCountY, long seed)
      Randomly subdivides the plane into equal-width strips having varying lengths.
      Parameters:
      width - width of the subdivision plane
      height - height of the subdivision plane
      gridCountX - horizontal grid count
      gridCountY - vertical grid count
      seed - the random seed
      Returns:
      a GROUP PShape, where each child shape is a face of the subdivision
      Since:
      1.3.0
    • sliceDivision

      public static processing.core.PShape sliceDivision(double width, double height, int slices, boolean forceOpposite, long seed)
      Divides the plane into randomly “sliced” polygonal regions.

      slices is the number of random interior cuts (line segments) to add across the plane (i.e., the number of cuts, not the number of resulting regions/pieces). These slices cuts are generated over a w×h rectangle at (0,0); each cut connects a random point on one side of the rectangle to a random point on another side. If forceOpposite is true, each cut always connects opposite sides; otherwise the two sides are chosen at random (but never the same side). The final number of polygonal regions depends on how the cuts intersect and partition the rectangle.

      In practice:

      • forceOpposite == true → mostly long, quadrilateral strips that span the full width or height of the rectangle.
      • forceOpposite == false → a richer variety of cell shapes (triangles, trapezoids, L-shapes, etc.) that may not stretch all the way across.

      Parameters:
      width - the width of the plane
      height - the height of the plane
      slices - the number of random interior cuts to perform
      forceOpposite - if true, each cut connects opposite sides of the rectangle; if false, cuts connect any two distinct sides
      seed - the random seed for reproducible slice placement
      Returns:
      a GROUP PShape containing the subdivided polygonal regions
      Since:
      2.1
    • arcDivision

      public static processing.core.PShape arcDivision(double width, double height, int arcs, long seed)
      Creates a cellular partition of the plane using arcs formed by circles seeded along its boundary. Each circle’s radius is chosen large enough to guarantee it intersects at least two distinct sides of the plane, forming an arc cut.

      In practice:

      • You get a “cellular” subdivision where each circle carves out roughly circular holes or bulges against the rectangle boundary.
      • Because every radius ≥ the minimum distance to a second side, each circle always spans at least two sides (forming an arc).

      Parameters:
      width - the width of the plane
      height - the height of the plane
      arcs - the number of circles to seed along the boundary
      circlePoints - the number of linear segments used to approximate each circle
      seed - the random seed for reproducible circle placement & radii
      Returns:
      a GROUP PShape containing the polygonal faces formed by the plane plus the seeded circles
      Since:
      2.1
    • doyleSpiral

      public static List<processing.core.PVector> doyleSpiral(double centerX, double centerY, int p, int q, double maxRadius)
      Generates a Doyle spiral. A Doyle spiral fills the plane with closely packed circles, where the radius of each circle in a packing is proportional to the distance of its centre from a central point. Each circle is tangent to six others that surround it by a ring of tangent circles
      Parameters:
      centerX - x coordinate of the center of the spiral
      centerY - y coordinate of the center of the spiral
      p - at least 2
      q - at least p + 1
      maxRadius - the maximum radius of the packing arrangement (the maximum distance a circle centroid can be from the center of the arrangement)
      Returns:
      A list of PVectors, each representing one circle in the spiral: (.x, .y) represent the center point and .z represents radius.
    • hexTiling

      public static processing.core.PShape hexTiling(double width, double height, double sideLength, boolean flat)
      Generates a hexagonal tiling of the plane.
      Parameters:
      width - width of the tiling plane
      height - height of the tiling plane
      sideLength - side length of each hexagon
      flat - determines the orientation of the hexagons -- whether the top is flat, or pointy
      Returns:
      a GROUP PShape, where each child shape is a hexagon of the tiling
    • islamicTiling

      public static processing.core.PShape islamicTiling(double width, double height, double w, double h)
      Generates an "islamic-style" (Girih) tiling of the plane.
      Parameters:
      width - width of the tiling plane
      height - height of the tiling plane
      w -
      h -
      Returns:
      a GROUP PShape, where each child shape is a tile of the tiling
    • penroseTiling

      public static processing.core.PShape penroseTiling(double centerX, double centerY, double radius, int steps)
      Generates a Penrose Tiling (consisting of rhombi).
      Parameters:
      centerX - x coordinate of the center/origin of the tiling
      centerY - y coordinate of the center/origin of the tiling
      radius - maximum radius of the tiling (measured from the center)
      steps - number of tiling subdivisions
      Returns:
      a GROUP PShape, where each child shape is a face of the tiling
    • squareTriangleTiling

      public static processing.core.PShape squareTriangleTiling(double width, double height, double tileSize)
      Generates a non-periodic tiling, comprising squares and equilateral triangles.
      Parameters:
      width - width of the tiling plane
      height - height of the tiling plane
      tileSize - diameter of each tile
      Returns:
      a GROUP PShape, where each child shape is a tile of the tiling
      Since:
      1.3.0
    • squareTriangleTiling

      public static processing.core.PShape squareTriangleTiling(double width, double height, double tileSize, long seed)
      Generates a non-periodic tiling, comprising squares and equilateral triangles, having a given seed.
      Parameters:
      width - width of the tiling plane
      height - height of the tiling plane
      tileSize - diameter of each tile
      seed - the random seed
      Returns:
      a GROUP PShape, where each child shape is a tile of the tiling
      Since:
      1.3.0
    • auxeticTiling

      public static processing.core.PShape auxeticTiling(double width, double height, double cellSize, int A, int B, int C)
      Builds a tiling of interlocking cells that form an auxetic structure.

      An auxetic structure tends to widen when stretched (it can show a negative Poisson’s ratio). This method builds a fabric/weave-like layout of horizontal and vertical segments then runs a Voronoi-like construction on those line segments. The resulting cell boundaries are made of straight and gently curved pieces, producing an interlocking tiling (which would have auxetic properties if physical).

      The A–B–C parameters

      The A-B-C parameters affect the underlying segment generation. Each row follows A cells with the horizontal (weft) thread on top, then B cells with the vertical (warp) thread on top. Each next row is shifted right by C cells (wraps around modulo P).

      What features appear, and when

      The Voronoi construction produces a small set of recurring unit-cell types. Below is a short, non-technical guide to what those features look like and the simple conditions that cause them to appear (using C' = C mod (A+B)):

      • Quad - four-armed vertex (a small “X-like” quad). Appears when the row-shift aligns with a run boundary: typically when A == C' or B == C'.
      • Tri-adjacent - the most common cell: two curved (parabolic) arcs meeting at a vertex plus a short straight edge. This cell shows up in nearly every weave except when the shift exactly matches a run length: it is absent if A == C' or B == C'.
      • Tri-across - a rarer symmetric three-armed cell formed by two mirrored parabolas and a straight ray across the vertex. It typically requires both runs to be at least length 2 and the shift to fall inside the interior of the repeat: occurs when A > 1, B > 1, and 1 < C' < A + B - 2.
      • Straight - long straight edges (horizontal or vertical) with a relatively small offset. These happen when the shift produces a significant mismatch with a run length, e.g. when |C' - A| > 1 (horizontal straight) or |C' - B| > 1 (vertical straight). Note that straight elements by themselves are not auxetic; changing how many straight elements occur can change the mechanical character of the cell but does not trivially predict Poisson’s ratio.
      Parameters:
      width - domain width
      height - domain height
      cellSize - size of a grid cell (world units), must be > 0
      A - number of consecutive cells where the horizontal (weft) thread is on top (A >= 1)
      B - number of consecutive cells where the vertical (warp) thread is on top (B >= 1)
      C - per-row horizontal shift (in cells), applied modulo A + B
      Returns:
      a PShape containing the Voronoi-derived cell boundaries (a weave-based auxetic lattice)
      Throws:
      IllegalArgumentException - if cellSize <= 0 or A <= 0 or B <= 0
      Since:
      2.2
      See Also:
    • annularBricks

      public static processing.core.PShape annularBricks(int nRings, double cx, double cy, double innerRadius, double ringGrowth, double segGrowth)
      Generates a geometric arrangement composed of annular-sector bricks arranged in concentric circular rings. Rings progressively expand from the inside out based on the growth rates provided. Brick sizes (arc length) adapt radially according to growth factors.
      Parameters:
      nRings - Number of annular rings to generate.
      cx - The x-coordinate of the center of the generated pattern.
      cy - The y-coordinate of the center of the generated pattern.
      innerRadius - The radius of the innermost ring in pixels.
      ringGrowth - The growth factor of each successive ring radius; values greater than 1.0 cause rings to expand radially outward.
      segGrowth - The growth factor controlling segment (brick) arc length adjustment along each ring; values greater than 1.0 increase brick length progressively outward.
      Returns:
      A single flattened PShape consisting of annular-sector bricks forming concentric rings around the specified center point (cx, cy).
      Since:
      2.1
    • aztecDiamond

      public static processing.core.PShape aztecDiamond(double originX, double originY, int order, double cellSize, long seed)
      Produces a random domino tiling of the Aztec diamond of the given order.

      The generated arrangement is positioned so that (originX, originY) is the center of the Aztec diamond. The tiling is generated on a unit grid and scaled by cellSize.

      Each child shape is one domino. The child name encodes an integer “class” identifying one of four standard domino types (horizontal/vertical orientation and checkerboard parity).

      Parameters:
      originX - x-coordinate of the center of the generated tiling.
      originY - y-coordinate of the center of the generated tiling.
      order - Aztec diamond order n; must be >= 1.
      cellSize - width/height of underlying grid cells; must be > 0.
      seed - seed used to initialise the RNG for reproducible tilings.
      Returns:
      a flattened PShape whose child faces are axis-aligned domino rectangles tiling the Aztec diamond; each child’s name encodes one of four domino classes.
      Since:
      2.2
    • softCells

      public static processing.core.PShape softCells(processing.core.PShape mesh, double ratio, micycle.pgs.commons.SoftCells.TangentMode mode, long seed)
      Generates a softened (curved) version of a tiling using the SoftCells edge-bending algorithm.

      The input mesh straight edges are softened into smooth, Bezier-like curves according to the supplied parameters. The resulting shape preserves the mesh topology (combinatorial adjacency) while altering the geometry to produce the characteristic "soft cell" appearance.

      The implementation samples random directions once per vertex (not per edge) when a stochastic tangent mode is selected. The seed only influences the following TangentMode values:

      • RANDOM - a random unit direction (one angle) is chosen once per vertex;
      • RANDOM_DIAGONAL - one of the two diagonal directions (diag1 or diag2) is chosen once per vertex;
      • RANDOM_60DEG - one of three 60° directions is selected once per vertex.
      Parameters:
      mesh - the input PShape representing the base tiling to be softened; must not be null. The input is not modified — a new PShape is returned.
      ratio - a floating-point control for the amount of softening/edge bending. Typical usage treats this as a normalised factor (commonly in the [0,1] range) where smaller values produce subtler curvature and larger values produce stronger softening (values much larger than may lead to face self-intersection).
      mode - the TangentMode that selects how half-tangents / edge directions are chosen and aligned during the edge-bending process; see TangentMode for available modes and behaviour.
      seed - random seed used to initialise the RNG. The seed only affects the stochastic tangent modes listed above; using the same seed with the same input mesh and parameters yields deterministic, repeatable output.
      Returns:
      a new PShape containing the softened tessellation (curved/soft cells) corresponding to the input mesh and parameters.
      Since:
      2.2