Package net.paulhertz.pixelaudio.curves

# Class PABezShape

java.lang.Object
net.paulhertz.pixelaudio.curves.PABezShape

public class PABezShape extends Object
Class to store a path composed of lines and Bezier curves, along with fill, stroke, weight and opacity values. Adapted from IgnoCodeLib Processing library for use with PixelAudio library. IgnoCodeLib is available in the Processing contributed libraries and at https://paulhertz.net/ignocodelib/ and https://github.com/Ignotus-mago/IgnoCodeLib3 TODO add write methods to save curves to a (JSON) file, create (JSON) file reader. TODO consider refactoring so that PApplet only need be passed in as an argument.

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `(package private) float[]`
  `bounds`
  left, top, right, bottom bounding rectangle
  `static final int`
  `CURVE_SEGMENT`
  flag for curve segment type, associated with PauBezVertex
  `private ArrayList<PAVertex2DINF>`
  `curves`
  list of bezier vertices
  `(package private) int`
  `fillColor`
  fill color for shape
  `(package private) boolean`
  `hasFill`
  flags if shape is filled or not
  `(package private) boolean`
  `hasStroke`
  flags if shape has a stroke or not
  `(package private) boolean`
  `isClosed`
  flags if shape is closed or not
  `(package private) boolean`
  `isMarked`
  flags we should draw control points and vertices
  `static final double`
  `KAPPA`
  In the approximation of a circle by Bezier curves,
  KAPPA = (distance between Bezier anchor and its associated control point) / (circle radius),
  when a circle is divided into 4 sectors of 90 degrees.
  KAPPA = 4 * (√2 - 1) / 3 = 0.5522847498
  `static final float`
  `LAMBDA`
  A value for weighting Bezier splines based on the length of line segments between anchor points, derived from the ratio of the chord of a quarter circle to KAPPA.
  `static final int`
  `LINE_SEGMENT`
  flag for line segment type, associated with LineVertex
  `(package private) int`
  `strokeColor`
  stroke color for shape
  `(package private) float`
  `weight`
  stroke weight for shape
  `(package private) float`
  `x`
  initial x-coordinate
  `(package private) float`
  `y`
  initial y-coordinate

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `PABezShape(float x, float y, boolean isClosed)`
  Creates a BezShape with initial point x,y, closed or open according to the value of isClosed.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `append(float x, float y)`
  Appends a LineVertex (line segment) to this BezShape.
  `void`
  `append(float cx1, float cy1, float cx2, float cy2, float x, float y)`
  Appends a PauBezVertex (cubic Bezier segment) to this BezShape.
  `void`
  `append(PAVertex2DINF vt)`
  Appends a Vertex2DINF to this BezShape
  `static int[]`
  `argbComponents(int argb)`
  Breaks a Processing color into A, R, G and B values in an array.
  `float`
  `bezierPoint(float a, float b, float c, float d, float t)`
  Evaluates the Bezier at point t for points a, b, c, d.
  `float`
  `bezierTangent(float a, float b, float c, float d, float t)`
  Calculates the tangent of a point on a Bézier curve.
  `protected float[]`
  `bounds()`
  Calculates the boundary rectangle of this shape and returns it as an array of floats.
  `PABezShape`
  `clone()`
  Creates a deep copy of this BezShape.
  `static int`
  `composeColor(int gray)`
  Creates a Processing ARGB color from a grayscale value.
  `static int`
  `composeColor(int[] comp)`
  Creates a Processing ARGB color from r, g, b, values in an array.
  `static int`
  `composeColor(int r, int g, int b)`
  Creates an opaque Processing RGB color from r, g, b values.
  `static final int`
  `composeColor(int r, int g, int b, int a)`
  Creates a Processing ARGB color from r, g, b, and alpha channel values.
  `ListIterator<PAVertex2DINF>`
  `curveIterator()`
  Returns an iterator over the geometry of this shape.
  `void`
  `draw(processing.core.PApplet parent)`
  Draws this shape to the display.
  `void`
  `draw(processing.core.PGraphics pg)`
  Draws this shape to an offscreen PGraphics.
  `void`
  `drawQuick(processing.core.PApplet parent)`
  Draws this shape to the display.
  `void`
  `drawQuick(processing.core.PGraphics pg)`
  Draws this shape to a PGraphics passed as an argument.
  `int`
  `fillColor()`
  `int`
  `fillOpacity()`
  `float[]`
  `getBounds()`
  `processing.core.PVector`
  `getBoundsCenter()`
  `ArrayList<processing.core.PVector>`
  `getPointList(int steps)`
  Extracts an approximated polygon from path data, returning it as an array of PVector.
  `ArrayList<processing.core.PVector>`
  `getPointList(processing.core.PApplet parent, int steps)`
  Deprecated.
  `ArrayList<processing.core.PVector>`
  `getPointList(processing.core.PGraphics pg, int steps)`
  Deprecated.
  `boolean`
  `hasFill()`
  `boolean`
  `hasStroke()`
  `boolean`
  `isClosed()`
  `boolean`
  `isMarked()`
  `int`
  `pointCount()`
  Returns number of points (anchor points and control points) in curves.
  `static boolean`
  `pointInPoly(ArrayList<processing.core.PVector> poly, float x, float y)`
  Decides if a point is inside a polygon, returns true if it is.
  `static int[]`
  `rgbaComponents(int argb)`
  Breaks a Processing color into R, G, B and A values in an array.
  `static int[]`
  `rgbComponents(int rgb)`
  Breaks a Processing color into R, G and B values in an array.
  `static processing.core.PVector`
  `rotateCoordAroundPoint(float x, float y, float xctr, float yctr, float theta)`
  Rotates a point theta radians around a point (xctr, yctr), returns a new point.
  `void`
  `rotateShape(float xctr, float yctr, float theta)`
  Rotates this shape around a supplied center point.
  `static processing.core.PVector`
  `scaleCoordAroundPoint(float x, float y, float xScale, float yScale, float xctr, float yctr)`
  Scales a point by xScale and yScale around a point (xctr, yctr), returns a new point.
  `void`
  `scaleShape(float xScale, float yScale, float x0, float y0)`
  Scales this shape around a given point.
  `void`
  `setBounds(float[] newBounds)`
  `void`
  `setFillColor(int newFillColor)`
  `void`
  `setFillOpacity(int opacity)`
  Sets opacity of current fill color.
  `void`
  `setHasFill(boolean newHasFill)`
  `void`
  `setHasStroke(boolean newHasStroke)`
  `void`
  `setIsClosed(boolean newIsClosed)`
  `void`
  `setIsMarked(boolean newIsMarked)`
  `void`
  `setNoFill()`
  Marks this component as having no fill.
  `void`
  `setNoStroke()`
  Marks this component as having no stroke Equivalent to setHasStroke(false), if the implementor provides a setHasStroke method
  `void`
  `setStartPoint(float newX, float newY)`
  Sets a new initial vertex for this BezShape.
  `void`
  `setStrokeColor(int newStrokeColor)`
  `void`
  `setStrokeOpacity(int opacity)`
  Sets opacity of current stroke color.
  `void`
  `setWeight(float newWeight)`
  `void`
  `setX(float newX)`
  Sets the x-coordinate of the initial point of the geometry of this shape.
  `void`
  `setY(float newY)`
  Sets the y-coordinate of the initial point of the geometry of this shape.
  `int`
  `size()`
  Returns size of number of vertices (PauBezVertex and LineVertex) in curves.
  `PALineVertex`
  `startVertex()`
  `int`
  `strokeColor()`
  `int`
  `strokeOpacity()`
  `static processing.core.PVector`
  `translateCoord(float x, float y, float xOffset, float yOffset)`
  Translates a point by xOffset and yOffset, returns a new point.
  `void`
  `translateShape(float xTrans, float yTrans)`
  Translates this shape in x and y directions.
  `float`
  `weight()`
  Returns the current weight (in points) of stroked lines.
  `float`
  `x()`
  Returns the x-coordinate of the initial point of the geometry of this shape.
  `float`
  `y()`
  Returns the y-coordinate of the initial point of the geometry of this shape.

  ### Methods inherited from class java.lang.Object

  `equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## Field Details

  - ### x

    float x
    initial x-coordinate

  - ### y

    float y
    initial y-coordinate

  - ### curves

    private ArrayList<PAVertex2DINF> curves
    list of bezier vertices

  - ### isClosed

    boolean isClosed
    flags if shape is closed or not

  - ### isMarked

    boolean isMarked
    flags we should draw control points and vertices

  - ### LINE_SEGMENT

    public static final int LINE_SEGMENT
    flag for line segment type, associated with LineVertex
    See Also:
      - Constant Field Values

  - ### CURVE_SEGMENT

    public static final int CURVE_SEGMENT
    flag for curve segment type, associated with PauBezVertex
    See Also:
      - Constant Field Values

  - ### hasFill

    boolean hasFill
    flags if shape is filled or not

  - ### hasStroke

    boolean hasStroke
    flags if shape has a stroke or not

  - ### fillColor

    int fillColor
    fill color for shape

  - ### strokeColor

    int strokeColor
    stroke color for shape

  - ### weight

    float weight
    stroke weight for shape

  - ### bounds

    float[] bounds
    left, top, right, bottom bounding rectangle

  - ### KAPPA

    public static final double KAPPA

    In the approximation of a circle by Bezier curves,
    KAPPA = (distance between Bezier anchor and its associated control point) / (circle radius),
    when a circle is divided into 4 sectors of 90 degrees.
    KAPPA = 4 * (√2 - 1) / 3 = 0.5522847498

    See Also:
      - http://www.whizkidtech.redprince.net/bezier/circle/kappa/
      - Constant Field Values

  - ### LAMBDA

    public static final float LAMBDA
    A value for weighting Bezier splines based on the length of line segments between anchor points, derived from the ratio of the chord of a quarter circle to KAPPA. LAMBDA = KAPPA * (1/√2) = 0.39052429175f
    See Also:
      - Constant Field Values

- ## Constructor Details

  - ### PABezShape

    public PABezShape(float x, float y, boolean isClosed)
    Creates a BezShape with initial point x,y, closed or open according to the value of isClosed. Fill, stroke, and weight of shapes are set from their values in the Processing environment. The Processing transformation matrix (set by calls to rotate, translate and scale) is saved to the instance variable `ctm`, but no transform is performed. Note that drawing is affected by the current Processing transform.
    Parameters:
      `parent` - PApplet used for calls to the Processing environment, notably for drawing
      `x` - x-coordinate of initial point
      `y` - y-coordinate of initial point
      `isClosed` - true if shape is closed, false if it is open

- ## Method Details

  - ### x

    public float x()
    Returns the x-coordinate of the initial point of the geometry of this shape.
    Returns:
      x-coordinate of initial vertex

  - ### setX

    public void setX(float newX)
    Sets the x-coordinate of the initial point of the geometry of this shape.
    Parameters:
      `newX` - new x-coordinate of initial vertex

  - ### y

    public float y()
    Returns the y-coordinate of the initial point of the geometry of this shape.
    Returns:
      y-coordinate of initial vertex

  - ### setY

    public void setY(float newY)
    Sets the y-coordinate of the initial point of the geometry of this shape.
    Parameters:
      `newY` - new y-coordinate of initial vertex

  - ### startVertex

    public PALineVertex startVertex()
    Returns:
      a PauLineVertex with start point coordinates of this shape

  - ### setStartPoint

    public void setStartPoint(float newX, float newY)
    Sets a new initial vertex for this BezShape.
    Parameters:
      `newX` -
      `newY` -

  - ### isClosed

    public boolean isClosed()
    Returns:
      `true` if this shape is closed, `false` otherwise.

  - ### setIsClosed

    public void setIsClosed(boolean newIsClosed)
    Parameters:
      `newIsClosed` - `true` if this shape is closed, `false` otherwise

  - ### isMarked

    public boolean isMarked()
    Returns:
      `true` if this shape is marked with vertices and control points, `false` otherwise.

  - ### setIsMarked

    public void setIsMarked(boolean newIsMarked)
    Parameters:
      `newIsMarked` - `true` if this shape is marked with vertices and control points, `false` otherwise

  - ### hasFill

    public boolean hasFill()
    Returns:
      true if this component is filled, false otherwise

  - ### setHasFill

    public void setHasFill(boolean newHasFill)
    Parameters:
      `newHasFill` - pass true if this shape has a fill, false otherwise. Note that the current fillColor will not be discarded by setting hasFill to false: the shape simply won't display or save to file with a fill.

  - ### setNoFill

    public void setNoFill()
    Marks this component as having no fill. Equivalent to setHasFill(false), if the implementor provides a setHasFill method

  - ### hasStroke

    public boolean hasStroke()
    Returns:
      true if this shape is stroked, false otherwise

  - ### setHasStroke

    public void setHasStroke(boolean newHasStroke)
    Parameters:
      `newHasStroke` - pass true if this shape has a stroke, false otherwise. Note that the current strokeColor will not be discarded by setting hasStroke to false: the shape simply won't display or save to file with a stroke.

  - ### setNoStroke

    public void setNoStroke()
    Marks this component as having no stroke Equivalent to setHasStroke(false), if the implementor provides a setHasStroke method

  - ### fillColor

    public int fillColor()
    Returns:
      the current fill color

  - ### setFillColor

    public void setFillColor(int newFillColor)
    Parameters:
      `newFillColor` - a Processing color (32-bit int with ARGB bytes).

  - ### strokeColor

    public int strokeColor()
    Returns:
      the current stroke color

  - ### setStrokeColor

    public void setStrokeColor(int newStrokeColor)
    Parameters:
      `newStrokeColor` - a Processing color (32-bit int with ARGB bytes).

  - ### setFillOpacity

    public void setFillOpacity(int opacity)
    Sets opacity of current fill color.
    Parameters:
      `opacity` - a number in the range 0..255. Value is not checked!

  - ### fillOpacity

    public int fillOpacity()
    Returns:
      the opacity value of the current fill color

  - ### setStrokeOpacity

    public void setStrokeOpacity(int opacity)
    Sets opacity of current stroke color.
    Parameters:
      `opacity` - a number in the range 0..255. Value is not checked!

  - ### strokeOpacity

    public int strokeOpacity()
    Returns:
      the opacity value of the current stroke color

  - ### weight

    public float weight()
    Returns the current weight (in points) of stroked lines.
    Returns:
      the current weight (in points) of stroked lines. One point = one pixel on screen.

  - ### setWeight

    public void setWeight(float newWeight)
    Parameters:
      `newWeight` - the new weight of stroked lines.

  - ### rgbComponents

    public static int[] rgbComponents(int rgb)
    Breaks a Processing color into R, G and B values in an array.
    Parameters:
      `rgb` - a Processing color as a 32-bit integer
    Returns:
      an array of 3 integers in the intRange 0..255 for 3 primary color components: {R, G, B}

  - ### argbComponents

    public static int[] argbComponents(int argb)
    Breaks a Processing color into A, R, G and B values in an array.
    Parameters:
      `argb` - a Processing color as a 32-bit integer
    Returns:
      an array of 4 integers in the range 0..255 for each color component: {A, R, G, B}

  - ### rgbaComponents

    public static int[] rgbaComponents(int argb)
    Breaks a Processing color into R, G, B and A values in an array.
    Parameters:
      `argb` - a Processing color as a 32-bit integer
    Returns:
      an array of integers in the intRange [0, 255] for 3 primary color components: {R, G, B} plus alpha

  - ### composeColor

    public static int composeColor(int r, int g, int b)
    Creates an opaque Processing RGB color from r, g, b values. Note the order of arguments, the same as the Processing color(value1, value2, value3) method.
    Parameters:
      `r` - red component [0, 255]
      `g` - green component [0, 255]
      `b` - blue component [0, 255]
    Returns:
      a 32-bit integer with bytes in Processing format ARGB.

  - ### composeColor

    public static final int composeColor(int r, int g, int b, int a)
    Creates a Processing ARGB color from r, g, b, and alpha channel values. Note the order of arguments, the same as the Processing color(value1, value2, value3, alpha) method.
    Parameters:
      `r` - red component [0, 255]
      `g` - green component [0, 255]
      `b` - blue component [0, 255]
      `a` - alpha component [0, 255]
    Returns:
      a 32-bit integer with bytes in Processing format ARGB.

  - ### composeColor

    public static int composeColor(int[] comp)
    Creates a Processing ARGB color from r, g, b, values in an array.
    Parameters:
      `comp` - array of 3 integers in range [0, 255], for red, green and blue components of color alpha value is assumed to be 255
    Returns:
      a 32-bit integer with bytes in Processing format ARGB.

  - ### composeColor

    public static int composeColor(int gray)
    Creates a Processing ARGB color from a grayscale value. Alpha is set to 255.
    Parameters:
      `gray` - a grayscale value 0..255
    Returns:
      an int compatible with a Processing color

  - ### append

    public void append(PAVertex2DINF vt)
    Appends a Vertex2DINF to this BezShape
    Parameters:
      `vt` - a PauVertex2DINF (line segment or curve segment)

  - ### append

    public void append(float cx1, float cy1, float cx2, float cy2, float x, float y)
    Appends a PauBezVertex (cubic Bezier segment) to this BezShape.
    Parameters:
      `cx1` - x-coordinate of first control point
      `cy1` - y-coordinate of first control point
      `cx2` - x-coordinate of second control point
      `cy2` - y-coordinate of second control point
      `x` - x-coordinate of terminal anchor point
      `y` - y-coordinate of terminal anchor point

  - ### append

    public void append(float x, float y)
    Appends a LineVertex (line segment) to this BezShape.
    Parameters:
      `x` -
      `y` -

  - ### curveIterator

    public ListIterator<PAVertex2DINF> curveIterator()
    Returns an iterator over the geometry of this shape. Preferred method for accessing geometry. Does not include the initial point, call x() and y() or startVertex() for that.
    Returns:
      an iterator over the PauVertex2DINF segments that comprise the geometry of this shape

  - ### size

    public int size()
    Returns size of number of vertices (PauBezVertex and LineVertex) in curves.
    Returns:
      size of curves ArrayList.

  - ### pointCount

    public int pointCount()
    Returns number of points (anchor points and control points) in curves. Dosn't count the start point.
    Returns:
      total numbr of points in curves ArrayList data.

  - ### clone

    public PABezShape clone()
    Creates a deep copy of this BezShape.
    Overrides:
      `clone` in class `Object`
    See Also:
      - `Object.clone()`

  - ### drawQuick

    public void drawQuick(processing.core.PApplet parent)
    Draws this shape to the display. Calls beginShape and endShape on its own. Uses current fill, stroke and weight from Processing environment.

  - ### drawQuick

    public void drawQuick(processing.core.PGraphics pg)
    Draws this shape to a PGraphics passed as an argument. Calls beginShape and endShape on its own. Uses current fill, stroke and weight from Processing environment.

  - ### draw

    public void draw(processing.core.PApplet parent)
    Draws this shape to the display. Calls beginShape and endShape on its own. If isMarked is true, will mark anchor and control points.

  - ### draw

    public void draw(processing.core.PGraphics pg)
    Draws this shape to an offscreen PGraphics. Calls beginShape and endShape on its own. It's up to the user to call beginDraw() and endDraw() on the PGraphics instance. If isMarked is true, draws marks for anchor and control points.
    Parameters:
      `pg` - a PGraphics instance

  - ### getPointList

    @Deprecated public ArrayList<processing.core.PVector> getPointList(processing.core.PApplet parent, int steps)
    Deprecated.
    Extracts an approximated polygon from path data, returning it as an array of PVector. We no longer require a PApplet instance to calculate the bezierPoint.
    Parameters:
      `parent` - a PApplet instance
      `steps` - number of straight line segments to divide Bezier curves into
    Returns:
      ArrayList of PVector, coordinates for a polygon approximation of this shape.

  - ### getPointList

    public ArrayList<processing.core.PVector> getPointList(int steps)
    Extracts an approximated polygon from path data, returning it as an array of PVector.
    Parameters:
      `steps` - number of straight line segments to divide Bezier curves into
    Returns:
      ArrayList of PVector, coordinates for a polygon approximation of this shape.

  - ### getPointList

    @Deprecated public ArrayList<processing.core.PVector> getPointList(processing.core.PGraphics pg, int steps)
    Deprecated.
    Extracts an approximated polygon from path data, returning it as an array of PVector. We no longer require a PGraphics instance to calculate the bezierPoint.
    Parameters:
      `pg` - a PGraphics instance
      `steps` - number of straight line segments to divide Bezier curves
    Returns:
      ArrayList of PVector, coordinates for a polygon approximation of this shape.

  - ### bezierPoint

    public float bezierPoint(float a, float b, float c, float d, float t)

    Evaluates the Bezier at point t for points a, b, c, d. The parameter t varies between 0 and 1, a and d are points on the curve, and b and c are the control points. This can be done once with the x coordinates and a second time with the y coordinates to get the location of a Bézier curve at t. Evaluation takes multiple calls, once each for x and y coordinates, in two dimensions.

    Parameters:
      `a` - coordinate of first point on the curve
      `b` - coordinate of first control point
      `c` - coordinate of second control point
      `d` - coordinate of second point on the curve
      `t` - value between 0 and 1
    Returns:
      single coordinate value of a point on the curve
    See Also:
      - https://github.com/benfry/processing4/blob/main/core/src/processing/core/PGraphics.java#L3369

  - ### bezierTangent

    public float bezierTangent(float a, float b, float c, float d, float t)

    Calculates the tangent of a point on a Bézier curve. There is a good definition of tangent on Wikipedia. Evaluation takes multiple calls, once each for x and y coordinates, in two dimensions.

    ### From Processing GitHub repo:

    Code submitted by Dave Bollinger (davbol) for release 0136.

    Parameters:
      `a` - coordinate of first point on the curve
      `b` - coordinate of first control point
      `c` - coordinate of second control point
      `d` - coordinate of second point on the curve
      `t` - value between 0 and 1
    Returns:
      a single coordinate value of endpoint of the tangent
    See Also:
      - https://github.com/benfry/processing4/blob/main/core/src/processing/core/PGraphics.java#L3360

  - ### bounds

    protected float[] bounds()
    Calculates the boundary rectangle of this shape and returns it as an array of floats.
    Returns:
      [xMin, yMin, xMax, yMax]

  - ### getBounds

    public float[] getBounds()
    Returns:
      bounding rectangle of this shape as an array of floats, [xMin, yMin, xMax, yMax]

  - ### setBounds

    public void setBounds(float[] newBounds)

  - ### getBoundsCenter

    public processing.core.PVector getBoundsCenter()

  - ### translateShape

    public void translateShape(float xTrans, float yTrans)
    Translates this shape in x and y directions.
    Parameters:
      `xTrans` -
      `yTrans` -

  - ### scaleShape

    public void scaleShape(float xScale, float yScale, float x0, float y0)
    Scales this shape around a given point. Sets xcoords and ycoords arrays to null: they will have to be recalculated after a transform, which will be done through lazy initialization when `xcoords()` or `ycoords()` are called.
    Parameters:
      `xScale` - scaling on x-axis
      `yScale` - scaling on y-axis

  - ### rotateShape

    public void rotateShape(float xctr, float yctr, float theta)
    Rotates this shape around a supplied center point.
    Parameters:
      `theta` - degrees to rotate (in radians) TODO for theta very near PI, 0, or TWO_PI, insure correct rotation.

  - ### translateCoord

    public static processing.core.PVector translateCoord(float x, float y, float xOffset, float yOffset)
    Translates a point by xOffset and yOffset, returns a new point.
    Parameters:
      `x` - x coordinate of point
      `y` - y coordinate of point
      `xOffset` - distance to translate on x-xis
      `yOffset` - distance to translate on y-axis
    Returns:
      a new translated point

  - ### scaleCoordAroundPoint

    public static processing.core.PVector scaleCoordAroundPoint(float x, float y, float xScale, float yScale, float xctr, float yctr)
    Scales a point by xScale and yScale around a point (xctr, yctr), returns a new point.
    Parameters:
      `x` - x coordinate of point
      `y` - y coordinate of point
      `xScale` - scaling on x-axis
      `yScale` - scaling on y-axis
      `xctr` - x coordinate of center of transformation
      `yctr` - y coordinate of center of transformation
    Returns:
      a new scaled point as a PVector

  - ### rotateCoordAroundPoint

    public static processing.core.PVector rotateCoordAroundPoint(float x, float y, float xctr, float yctr, float theta)
    Rotates a point theta radians around a point (xctr, yctr), returns a new point. rotation is counterclockwise for positive theta in Cartesian system, clockwise in screen display coordinate system
    Parameters:
      `x` - x coordinate of point
      `y` - y coordinate of point
      `xctr` - x coordinate of center of rotation
      `yctr` - y coordinate of center of rotation
      `theta` - angle to rotate, in radians
    Returns:
      a new rotated point

  - ### pointInPoly

    public static boolean pointInPoly(ArrayList<processing.core.PVector> poly, float x, float y)
    Decides if a point is inside a polygon, returns true if it is.
    Parameters:
      `npol` - number of points in polygon
      `poly` - an array of PVectors representing a polygon
      `x` - x-coordinate of point
      `y` - y-coordinate of point
    Returns:
      true if point is in polygon, false otherwise