Class Path2DInfo

java.lang.Object
org.bzdev.geom.Path2DInfo

public class Path2DInfo extends Object
Class providing static methods to obtain information about paths defined by java.awt.geom.Path2D.

The method shiftClosedPath(Path2D,double,double) returns a modified path (the same path as its argument but with its starting point shifted). The classes Paths2D and PathSplitter will allow various paths to be constructed.

  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    static class 
    Class defining a list entry describing a path segment.
    static enum 
    Enumeration naming Locations along a path.
    static final class 
    Class to store values used in computations on a segment of a path.
    static final class 
    Class to represent a value of the path parameter u.
  • Method Summary

    Modifier and Type
    Method
    Description
    static double
    Compute the area of a shape specified by a path iterator, using the differential form xdy - ydx.
    static double
    areaOf(PathIterator pi, boolean xdy)
    Compute the area of a shape specified by a path iterator, using the differential form xdy or -ydx.
    static double
    Compute the area of a shape specified by a path iterator and affine transformation.
    static double
    areaOf(Shape shape)
    Compute the area of a shape.
    static double
    Compute the area of a shape modified by an affine transformation.
    static Point2D
    Compute the center of mass of a shape, assuming the area has a uniform density.
    static Point2D
    Compute the center of mass of a shape, optionally modified by an affine transformation assuming the area has a uniform density.
    static double
    Compute the circumference of a shape.
    static double
    Compute the circumference of a shape modified by an affine transform.
    static Path2D
    controlPointPolygon(Path2D path, boolean all, AffineTransform af)
    Get a polygon connecting a path's control points.
    static Path2D
    convexHull(double[] coords, int offset, int n)
    Compute the convex hull of a set of control points.
    static Path2D
    convexHull(double x, double y, double[] coords, int n)
    Compute the convex hull of a set of control points.
    static Path2D
    convexHull(double x, double y, double[] coords, int offset, int n)
    Compute the convex hull of a set of control points.
    static double
    cubicLength(double u, double x0, double y0, double[] coords)
    Compute the length of a cubic path segment from its start to a position specified by the path parameter.
    cubicLengthFunction(double x0, double y0, double[] coords)
    Compute a function that provides the length of a cubic path segment from its start to a position specified by the path parameter.
    static double
    curvature(double u, double x0, double y0, int type, double[] coords)
    Compute the signed curvature given path-segment parameters.
    static boolean
    curvatureExists(double u, double x0, double y0, int type, double[] coords)
    Determine if the arguments allow the curvature to be computed.
    static double
    d2sDu2(double u, double x0, double y0, int type, double[] coords)
    Compute the second derivative of the path length s with respect to u given path-segment parameters.
    static double
    d2xDu2(double u, double x0, double y0, int type, double[] coords)
    Compute the second derivative of x with respect to u given path-segment parameters.
    static double
    d2yDu2(double u, double x0, double y0, int type, double[] coords)
    Compute the second derivative of y with respect to u given path-segment parameters.
    static double
    d3xDu3(double u, double x0, double y0, int type, double[] coords)
    Compute the third derivative of x with respect to u given path-segment parameters.
    static double
    d3yDu3(double u, double x0, double y0, int type, double[] coords)
    Compute the third derivative of y with respect to u given path-segment parameters.
    static double
    dsDu(double u, double x0, double y0, int type, double[] coords)
    Compute the derivative of the path length s with respect to the path's parameter u given path-segment parameters.
    static double
    dxDu(double u, double x0, double y0, int type, double[] coords)
    Compute dx/du given path-segment parameters.
    static double
    dyDu(double u, double x0, double y0, int type, double[] coords)
    Compute dy/du given path-segment parameters.
    static void
    elevateDegree(int degree, double[] result, double x, double y, double[] coords)
    Elevate the degree of a two-dimensional Bézier curve of degree n by 1, specifying the last n control points of the original curve in an array.
    static void
    elevateDegree(int degree, double[] result, int rOffset, double[] coords, int cOffset)
    Elevate the degree of a two-dimensional Bézier curve by 1.
    static double[]
    Get the normal vector for the start of a path.
    static double[]
    Get the tangent vector for the start of a path.
    static double[]
    getControlPoints(Path2D path, boolean all)
    List the control points of a path.
    static double[]
    getControlPoints(PathIterator pit, boolean all)
    List the control points of a path specified by a path iterator.
    Get a list of CPoint objects that can be used to configure a spline-path builder.
    Get a list of entries describing a path's segments or those for the outline of a shape.
    Get a list of entries describing a path's segments or those for the outline of a shape, modified by an affine transform.
    static boolean
    getLineIntersectionUV(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double[] uv, int offset)
    Get the path parameters for the intersection of two lines.
    static boolean
    getLineIntersectionUVXY(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double[] uvxy, int offset)
    Get the path parameters and the intersection point for the intersection of two lines.
    static boolean
    getLineIntersectionXY(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double[] xy, int offset)
    Get the intersection of two lines.
    static double
    getMinDistBezierParm(Point2D p, double x0, double y0, double[] coords, int degree)
    Find the parameter for a Bézier curve for the point on the curve closest to a specified point.
    static boolean
    getNormal(double u, double[] array, int offset, double x0, double y0, int type, double[] coords)
    Get the normal vector for a given value of the path parameter and an offset for the array storing the normal vector.
    static boolean
    getNormal(Path2D path, Path2DInfo.Location location, double[] array, int offset)
    Get the normal vector at the start or end of a path.
    Get a path iterator for the path implied by two cubic splines.
    static double[]
    getSegmentIntersectionUV(int type1, double x1, double y1, double[] coords1, int type2, double x2, double y2, double[] coords2)
    Get the path parameters for intersection of two Path2D segments.
    static double[]
    getSegmentIntersectionUVXY(int type1, double x1, double y1, double[] coords1, int type2, double x2, double y2, double[] coords2)
    Get the intersection of two Path2D segments, providing both path parameters and XY coordinates.
    static double[]
    getSegmentIntersectionXY(int type1, double x1, double y1, double[] coords1, int type2, double x2, double y2, double[] coords2)
    Get the intersection of two Path2D segments.
    static Point2D
    Get the starting point along a path.
    static boolean
    getTangent(double u, double[] array, int offset, double x0, double y0, int type, double[] coords)
    Get the tangent vector for a specified value of the path parameter and an output-array offset.
    static boolean
    getTangent(Path2D path, Path2DInfo.Location location, double[] array, int offset)
    Get the tangent vector at the start or end of a path.
    static String
    getTypeString(int type)
    Get the type of a path-iterator item, formatted as a string
    static double
    getX(double u, double x0, double y0, int type, double[] coords)
    Compute the X coordinate of a point on the path given path-segment parameters.
    static double
    getY(double u, double x0, double y0, int type, double[] coords)
    Compute the Y coordinate of a point on a path given path-segment parameters.
    static boolean
    Determine if a path is oriented clockwise when traversed in the direction of an increasing path parameter.
    static boolean
    Determine if the first continuous portion of a path is closed.
    static boolean
    Determine if a path is oriented counterclockwise when traversed in the direction of an increasing path parameter.
    static double[]
    Get the normal vector for the end of a path.
    static double[]
    Get the tangent vector for the end of a path.
    static boolean
    lineSegmentsIntersect(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
    Determine if two line segments intersect.
    static double[][]
    momentsOf(Point2D center, Shape shape)
    Get the moments for the area inside a shape about a reference point.
    static double[][]
    momentsOf(Point2D center, Shape shape, AffineTransform af)
    Get the moments for the area inside a shape about a reference point after applying an affine transform to both.
    static double[][]
    Get the moments about the center of mass for the area inside a shape.
    static double[][]
    Get the moments for the area inside a shape modified by an affine transformation and about the center of mass of the modified shape.
    static int
    Count the number of knots in the first continuous portion of a path that are Drawable.
    static int
    Count the number of segments in the first continuous portion of a path that are Drawable.
    static double
    Compute the length of a path or the length of an outline of a shape.
    static double
    pathLength(Shape path, int start, int end)
    Compute the length of a path or the length of an outline of a shape for a given range of path/outline segments.
    static double
    Compute the length of a path or the length of an outline of a shape, modified by an affine transform.
    static double
    pathLength(Shape path, AffineTransform at, int start, int end)
    Compute the length of a path or the length of an outline of a shape for a given range of path/outline segments, modified by an affine transform.
    static double[][]
    principalAxes(double[][] moments)
    Compute the principal axes corresponding a moments matrix.
    static double[]
    principalMoments(double[][] moments)
    Find the principle moments of a shape given its moments.
    static void
    Print information about the segments that make up a path, or the outline of a shape, to the standard output.
    static void
    printSegments(Appendable appendable, Shape s)
    Print information about the segments that make up a path or an outline of a shape.
    static void
    printSegments(String prefix, Appendable appendable, Shape s)
    Print information about the segments that make up a path or the outline of a shape, adding a prefix.
    static double
    quadLength(double u, double x0, double y0, double[] coords)
    Compute the length of a quadratic path segment from its start to a position specified by the path parameter.
    quadLengthFunction(double x0, double y0, double[] coords)
    Provide a function that computes the length of a quadratic path segment from its start to a position specified by a path parameter.
    static double
    segmentLength(double u, int type, double x0, double y0, double[] coords)
    Get the length of a subpath of a path segment.
    static double
    segmentLength(int type, double x0, double y0, double[] coords)
    Compute the length of a segment given parameters describing it.
    static double
    segmentLength(Shape p, int segment)
    Get the length of the ith segment of a path or of a shape's outline.
    segmentLengthFunction(int type, double x0, double y0, double[] coords)
    Provide a function to compute the length of a subpath of a path segment.
    static Path2D
    shiftClosedPath(Path2D path, double x, double y)
    Find the first closed component of a path that goes through a point (x, y) and shift that path component so it starts at (x, y).
    static double[][]
    toMomentsOfInertia(double[][] moments)
    Convert moments to moments of inertia.

    Methods inherited from class java.lang.Object

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

    • segmentLength

      public static double segmentLength(double u, int type, double x0, double y0, double[] coords) throws IllegalArgumentException
      Get the length of a subpath of a path segment.

      When the path parameter is PathIterator.SEG_CLOSE, the array must contain the X and Y coordinates of the path's initial point in that order.

      Parameters:
      u - the path parameter for the end of the subpath which includes all points on the path whose path parameters are in the range [0, u]
      type - either PathIterator.SEG_MOVETO PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, PathIterator.SEG_CUBICTO, or PathIterator.SEG_CLOSE
      x0 - the X coordinate at the start of the segment
      y0 - the Y cooredinate at the start of the segment
      coords - the remaining control points, with the X coordinate followed immediately by the Y coordinate for each
      Returns:
      the path-sgement length
      Throws:
      IllegalArgumentException - if the type argument is not recognized or if the fifth argument is null or is too short
    • segmentLengthFunction

      public static RealValuedFunctOps segmentLengthFunction(int type, double x0, double y0, double[] coords) throws IllegalArgumentException, ArithmeticException
      Provide a function to compute the length of a subpath of a path segment.

      When the path parameter is PathIterator.SEG_CLOSE, the array must contain the X and Y coordinates of the path's initial point in that order.

      Parameters:
      type - either PathIterator.SEG_MOVETO PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, PathIterator.SEG_CUBICTO, or PathIterator.SEG_CLOSE
      x0 - the X coordinate at the start of the segment
      y0 - the Y cooredinate at the start of the segment
      coords - the remaining control points, with the X coordinate followed immediately by the Y coordinate for each
      Returns:
      a function that computes the length of a subpath from path parameter 0 to the path parameter provided as the function's argument
      Throws:
      IllegalArgumentException - if the type argument is not recognized or if the fifth argument is null or is too short
      ArithmeticException - if a real-valued function could not be constructed
    • quadLength

      public static double quadLength(double u, double x0, double y0, double[] coords)
      Compute the length of a quadratic path segment from its start to a position specified by the path parameter.
      Parameters:
      u - the path parameter in the range [0.0, 1.0]
      x0 - the X coordinate of the first control point
      y0 - the Y coordinate of the first control point
      coords - the remaining control points in order, with even indices for X coordinates and odd indices for Y coordinates (only the first 4 indices will be used)
      Returns:
      the path length from u = 0 to the given value of u.
    • quadLengthFunction

      public static RealValuedFunctOps quadLengthFunction(double x0, double y0, double[] coords)
      Provide a function that computes the length of a quadratic path segment from its start to a position specified by a path parameter.
      Parameters:
      x0 - the X coordinate of the first control point
      y0 - the Y coordinate of the first control point
      coords - the remaining control points in order, with even indices for X coordinates and odd indices for Y coordinates (only the first 4 indices will be used)
      Returns:
      a function of the path parameter providing the length of a path segment from its start to the point specified by the path parameter provided as the function's argument
    • cubicLength

      public static double cubicLength(double u, double x0, double y0, double[] coords)
      Compute the length of a cubic path segment from its start to a position specified by the path parameter.
      Parameters:
      u - the path parameter in the range [0.0, 1.0]
      x0 - the X coordinate of the first control point
      y0 - the Y coordinate of the first control point
      coords - the remaining control points in order, with even indices for X coordinates and odd indices for Y coordinates (only the first 6 indices will be used)
      Returns:
      the path length from u = 0 to the given value of u.
    • cubicLengthFunction

      public static RealValuedFunctOps cubicLengthFunction(double x0, double y0, double[] coords)
      Compute a function that provides the length of a cubic path segment from its start to a position specified by the path parameter.
      Parameters:
      x0 - the X coordinate of the first control point
      y0 - the Y coordinate of the first control point
      coords - the remaining control points in order, with even indices for X coordinates and odd indices for Y coordinates (only the first 6 indices will be used)
      Returns:
      a function of the path parameter that computes the length of a path segment from its start to the point corresponding to the path parameter provided as the function's argument
    • getPathIterator

      public static PathIterator getPathIterator(AffineTransform af, CubicSpline x, CubicSpline y)
      Get a path iterator for the path implied by two cubic splines. The splines must have the same number of knots.
      Parameters:
      af - the affine transform to apply to the path iterator; null is equivalent to an identity transform
      x - the cubic spline for the X coordinates
      y - the cubic spline for the Y coordinates
      Returns:
      the path iterator
    • elevateDegree

      public static void elevateDegree(int degree, double[] result, int rOffset, double[] coords, int cOffset)
      Elevate the degree of a two-dimensional Bézier curve by 1. The algorithm is describe in Degree Elevation of a Bézier Curve. The length of the coords array must be at least 2*(degree+1), whereas the length of the result array must be at least 2*(degree+2).

      Control points are stored so that the X and Y coordinates for control point (i/2) are in array locations i and i+1 respectively, where i = 0 (mod 2).

      Parameters:
      degree - the degree of the original curve
      result - an array storing the control points for an the new curve
      rOffset - the offset into the result array at which the control points for the new curve will be stored
      coords - the array containing the control points for the original curve
      cOffset - the offset into the coords array at which the control points for the original curve start
    • elevateDegree

      public static void elevateDegree(int degree, double[] result, double x, double y, double[] coords)
      Elevate the degree of a two-dimensional Bézier curve of degree n by 1, specifying the last n control points of the original curve in an array. The length of the result array must be at least 2*(degree+1), whereas the length of the coords array must be at least 2*degree. The algorithm is describe in Degree Elevation of a Bézier Curve.

      Control points are stored so that the X and Y coordinates for control point (i/2)+1 are in array locations i and i+1 respectively, where i = 0 (mod 2).

      Parameters:
      degree - the degree of the curve
      result - an array storing the last n control points for the new curve, which excludes its starting point
      x - the X coordinate for the start of the curve (control point 0)
      y - the Y coordinate for the start of the curve (control point 0)
      coords - the array containing the last n-1 control points for the original curve, which excludes its starting point
    • getControlPoints

      public static double[] getControlPoints(Path2D path, boolean all)
      List the control points of a path.
      Parameters:
      path - the path
      all - true if all control points are included; false if only the control points starting or ending a segment are included
      Returns:
      an array containing the control points, each as a pair of values
    • getControlPoints

      public static double[] getControlPoints(PathIterator pit, boolean all)
      List the control points of a path specified by a path iterator.
      Parameters:
      pit - the path iterator providing the control points
      all - true if all control points are included; false if only the control points starting or ending a segment are included
      Returns:
      an array containing the control points, each as a pair of values
    • controlPointPolygon

      public static Path2D controlPointPolygon(Path2D path, boolean all, AffineTransform af)
      Get a polygon connecting a path's control points.
      Parameters:
      path - the path to process
      all - true if all control points should be included; false for just the 'knots' (the end-points of each segment)
      af - an affine transform to apply the path before processing; null for an identity transform
      Returns:
      a path consisting of straight-line segments
    • convexHull

      public static Path2D convexHull(double[] coords, int offset, int n)
      Compute the convex hull of a set of control points. The control points are stored in an array. This allows a convex hull to be computed using the arrays returned by PathIterator. Note: the implementation uses the gift-wrapping algorithm for trivial cases (see the Wikipedia description of this algorithm). For n ≥ 2, Andrew's monotone chain convex hull algorithm is used (the implementation is quite different than the Java code shown in this citation). For n>384, the Aki-Toussaint heuristic is used with an octagon estimate of the convex hull.

      The path that is returned is oriented so that each successive edge along the convex hull turns counter clockwise (e.g, from the positive X axis towards the positive Y axis) when axes use the the standard mathematical convention in which the positive X axis points right and the positive Y axis points up.

      Parameters:
      coords - the coordinates of the remaining control points, listed with X values of a point immediately followed by the Y value of the same point
      offset - the offset into the array coords where the data starts;
      n - the number of control points in the array (for Bézier curves, this is one more than the degree of the curve)
      Returns:
      a path whose segments are straight lines, providing the convex hull oriented so that the path is counterclockwise (turning from increasing X towards increasing Y)
    • convexHull

      public static Path2D convexHull(double x, double y, double[] coords, int n)
      Compute the convex hull of a set of control points. The initial control point is given explicitly by the x and y arguments and the remaining control points are stored in an array. This allows a convex hull to be computed using the arrays returned by PathIterator. Note: the implementation uses the gift-wrapping algorithm for trivial cases (see the Wikipedia description of this algorithm). For n ≥ 2, Andrew's monotone chain convex hull algorithm is used (the implementation is quite different than the Java code shown in this citation). For n>384, the Aki-Toussaint heuristic is used with an octagon estimate of the convex hull.

      The path that is returned is oriented so that each successive edge along the convex hull turns counter clockwise (e.g, from the positive X axis towards the positive Y axis) when axes use the the standard mathematical convention in which the positive X axis points right and the positive Y axis points up.

      Parameters:
      x - the X coordinate of the initial control point
      y - the Y coordinate of the initial control point
      coords - the coordinates of the remaining control points, listed with X values of a point immediately followed by the Y value of the same point
      n - the number of control points in the array (for Bézier curves, this is the degree of the curve)
      Returns:
      a path whose segments are straight lines, providing the convex hull oriented so that the path is counterclockwise (turning from increasing X towards increasing Y)
    • convexHull

      public static Path2D convexHull(double x, double y, double[] coords, int offset, int n)
      Compute the convex hull of a set of control points. The initial control point is given explicitly by the x and y arguments and the remaining control points are stored in an array. This allows a convex hull to be computed using the arrays returned by PathIterator. Note: the implementation uses the gift-wrapping algorithm for trivial cases (see the Wikipedia description of this algorithm). For n ≥ 2, Andrew's monotone chain convex hull algorithm is used (the implementation is quite different than the Java code shown in this citation). For n>384, the Aki-Toussaint heuristic is used with an octagon estimate of the convex hull.

      The path that is returned is oriented so that each successive edge along the convex hull turns counter clockwise (e.g, from the positive X axis towards the positive Y axis) when axes use the the standard mathematical convention in which the positive X axis points right and the positive Y axis points up.

      Parameters:
      x - the X coordinate of the initial control point
      y - the Y coordinate of the initial control point
      coords - the coordinates of the remaining control points, listed with X values of a point immediately followed by the Y value of the same point
      offset - the offset into the array coords where the data starts;
      n - the number of control points in the array (for Bézier curves, this is the degree of the curve)
      Returns:
      a path whose segments are straight lines, providing the convex hull oriented so that the path is counterclockwise (turning from increasing X towards increasing Y)
    • lineSegmentsIntersect

      public static boolean lineSegmentsIntersect(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
      Determine if two line segments intersect. The segments are assumed to have a finite length.

      For Java-7 (openjdk) and some other versions, there is a bug in Line2D.linesIntersect(double,double,double,double,double,double,double,double) where two nearly parallel but well separated line segments will appear to intersect. This method computes the same value, but using a different algorithm, and with better numerical stability.

      Parameters:
      x1 - the X coordinate for the start of the first line segment
      y1 - the Y coordinate for the start of the first line segment
      x2 - the X coordinate for the end of the first line segment
      y2 - the Y coordinate for the end of the first line segment
      x3 - the X coordinate for the start of the second line segment
      y3 - the Y coordinate for the start of the second line segment
      x4 - the X coordinate for the end of the second line segment
      y4 - the Y coordinate for the end of the second line segment
      Returns:
      true if the line segments intersect; false if they do not intersect
    • getLineIntersectionXY

      public static boolean getLineIntersectionXY(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double[] xy, int offset)
      Get the intersection of two lines. The first line is represented by the parameterized curve
       x = x1(1-u) + x2u
       y = y1(1-u) + y2u
       
      and the second line is represented by the parameterized curve
       x = x3(1-u) + x4u
       y = y3(1-u) + y4u
       
      If the lines to not intersect, the value false is returned and the XY coordinates of the intersection point are set to Double.NaN. The lines are considered to be of infinite length.
      Parameters:
      x1 - the X coordinate for the start of the first line segment
      y1 - the Y coordinate for the start of the first line segment
      x2 - the X coordinate for the end of the first line segment
      y2 - the Y coordinate for the end of the first line segment
      x3 - the X coordinate for the start of the second line segment
      y3 - the Y coordinate for the start of the second line segment
      x4 - the X coordinate for the end of the second line segment
      y4 - the Y coordinate for the end of the second line segment
      xy - an array that will contain the X value of the intersection point, at an offset into the array, followed by the Y value of the intersection point
      offset - the offset into the array xy so that xy[offset] contains the X component of the intersection point and xy[offset+1] contains the Y component of the intersection point
      Returns:
      true if the the lines intersect at a single point; false otherwise
    • getLineIntersectionUV

      public static boolean getLineIntersectionUV(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double[] uv, int offset)
      Get the path parameters for the intersection of two lines. The first line is represented by the parameterized curve
       x = x1(1-u) + x2u
       y = y1(1-u) + y2u
       
      and the second line is represented by the parameterized curve
       x = x3(1-v) + x4v
       y = y3(1-v) + y4v
       
      If the lines to not intersect, the value false is returned and the XY coordinates of the intersection point are set to Double.NaN. The lines are considered to be of infinite length. If a path parameter is between 0 and 1, the intersection point lies along the path segment used to define the line.
      Parameters:
      x1 - the X coordinate for the start of the first line segment
      y1 - the Y coordinate for the start of the first line segment
      x2 - the X coordinate for the end of the first line segment
      y2 - the Y coordinate for the end of the first line segment
      x3 - the X coordinate for the start of the second line segment
      y3 - the Y coordinate for the start of the second line segment
      x4 - the X coordinate for the end of the second line segment
      y4 - the Y coordinate for the end of the second line segment
      uv - an array containing the path parameters for the two paths
      offset - the offset into the array uv so that uv[offset] contains the path parameter u for the first line at the intersection point and so that uv[offset+1] contains the path parameter v for the second line at the intersection point contains the Y component of the intersection point
      Returns:
      true if the the lines intersect at a single point; false otherwise
    • getLineIntersectionUVXY

      public static boolean getLineIntersectionUVXY(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, double[] uvxy, int offset)
      Get the path parameters and the intersection point for the intersection of two lines. The first line is represented by the parameterized curve
       x = x1(1-u) + x2u
       y = y1(1-u) + y2u
       
      and the second line is represented by the parameterized curve
       x = x3(1-u) + x4u
       y = y3(1-u) + y4u
       
      If the lines to not intersect, the value false is returned and the u-v parameters and the XY coordinates of the intersection point are set to Double.NaN. The lines are considered to be of infinite length. If a path parameter is between 0 and 1, the intersection point lies along the path segment used to define the line.
      Parameters:
      x1 - the X coordinate for the start of the first line segment
      y1 - the Y coordinate for the start of the first line segment
      x2 - the X coordinate for the end of the first line segment
      y2 - the Y coordinate for the end of the first line segment
      x3 - the X coordinate for the start of the second line segment
      y3 - the Y coordinate for the start of the second line segment
      x4 - the X coordinate for the end of the second line segment
      y4 - the Y coordinate for the end of the second line segment
      uvxy - an array containing the path parameters for the two paths
      offset - the offset into the array uvxy so that uvxy[offset] contains the path parameter u for the first line at the intersection point, uvxy[offset+1] contains the path parameter v for the second line at the intersection point, uvxy[offset+2] contains the x coordinate of the intersection point, and uvxy[offset+3] contains the Y component of the intersection point
      Returns:
      true if the the lines intersect at a single point; false otherwise
    • getMinDistBezierParm

      public static double getMinDistBezierParm(Point2D p, double x0, double y0, double[] coords, int degree)
      Find the parameter for a Bézier curve for the point on the curve closest to a specified point.

      The calling convention matches the standard use of the interface PathIterator. As currently defined, the constants PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, and PathIterator.SEG_CUBICTO have integer values equal to the degree of the corresponding Bé curve, although is is safer to not depend on this being true in future versions of Java.

      Parameters:
      p - the specified point
      x0 - the initial control point's X coordinate
      y0 - the initial control point's Y coordinate
      coords - the coordinates for the remaining control points, listed in order as pairs of X-Y coordinates with X coordinates preceding Y coordinates
      degree - the degree of the Bézier curve (this is one half the minimum length for the coords array).
      Returns:
      the path parameter
    • getSegmentIntersectionUV

      public static double[] getSegmentIntersectionUV(int type1, double x1, double y1, double[] coords1, int type2, double x2, double y2, double[] coords2)
      Get the path parameters for intersection of two Path2D segments.
      Parameters:
      type1 - the type of the first segment (PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, or PathIterator.SEG_CUBICTO)
      x1 - the X coordinate of the first segment's initial control point
      y1 - the Y coordinate of the first segment's initial control point
      coords1 - the remaining control points for the first segment, listed in order with the X and Y coordinates adjacent and in that order (the same convention used by PathIterator.currentSegment(double[]))
      type2 - the type of the second segment (PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, or PathIterator.SEG_CUBICTO)
      x2 - the X coordinate of the second segment's initial control point
      y2 - the Y coordinate of the second segment's initial control point
      coords2 - the remaining control points for the second segment, listed in order with the X and Y coordinates adjacent and in that order (the same convention used by PathIterator.currentSegment(double[]))
      Returns:
      a array whose length is even and whose entries occur in pairs with an even entry containing the path parameter for the first curve followed by the path parameter for the second curve corresponding to an intersection.
    • getSegmentIntersectionXY

      public static double[] getSegmentIntersectionXY(int type1, double x1, double y1, double[] coords1, int type2, double x2, double y2, double[] coords2)
      Get the intersection of two Path2D segments.
      Parameters:
      type1 - the type of the first segment (PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, or PathIterator.SEG_CUBICTO)
      x1 - the X coordinate of the first segment's initial control point
      y1 - the Y coordinate of the first segment's initial control point
      coords1 - the remaining control points for the first segment, listed in order with the X and Y coordinates adjacent and in that order (the same convention used by PathIterator.currentSegment(double[]))
      type2 - the type of the second segment (PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, or PathIterator.SEG_CUBICTO)
      x2 - the X coordinate of the second segment's initial control point
      y2 - the Y coordinate of the second segment's initial control point
      coords2 - the remaining control points for the second segment, listed in order with the X and Y coordinates adjacent and in that order (the same convention used by PathIterator.currentSegment(double[]))
      Returns:
      a array whose length is even and whose entries occur in pairs with an even entry containing the X coordinate and the next entry containing the Y coordinate for an intersection of the two curves
    • getSegmentIntersectionUVXY

      public static double[] getSegmentIntersectionUVXY(int type1, double x1, double y1, double[] coords1, int type2, double x2, double y2, double[] coords2)
      Get the intersection of two Path2D segments, providing both path parameters and XY coordinates.
      Parameters:
      type1 - the type of the first segment (PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, or PathIterator.SEG_CUBICTO)
      x1 - the X coordinate of the first segment's initial control point
      y1 - the Y coordinate of the first segment's initial control point
      coords1 - the remaining control points for the first segment, listed in order with the X and Y coordinates adjacent and in that order (the same convention used by PathIterator.currentSegment(double[]))
      type2 - the type of the second segment (PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, or PathIterator.SEG_CUBICTO)
      x2 - the X coordinate of the second segment's initial control point
      y2 - the Y coordinate of the second segment's initial control point
      coords2 - the remaining control points for the second segment, listed in order with the X and Y coordinates adjacent and in that order (the same convention used by PathIterator.currentSegment(double[]))
      Returns:
      a array whose length is even and whose entries occur in quartets in the following order:
      • the path parameter for the first curve at an intersection
      • the path parameter for the second curve at an intersection
      • the X coordinate for the intersection
      • the Y coordinate for the intersection
      with this sequence repeated for as many intersections as was found; null if there are no intersections.
    • getX

      public static double getX(double u, double x0, double y0, int type, double[] coords) throws IllegalArgumentException
      Compute the X coordinate of a point on the path given path-segment parameters. When the type is PathIterator.SEG_MOVETO, x0 and y0 are ignored. When the type is PathIterator.SEG_CLOSE, the first two elements of coords must be set to the X and Y coordinate respectively for the point provided by most recent segment whose type is PathIterator.SEG_MOVETO.
      Parameters:
      u - the path-segment parameter in the range [0,1]
      x0 - the X coordinate of the point on the segment for u = 0
      y0 - the Y coordinate of the point on the segment for u = 0
      type - the segment type as defined by PathIterator (values may be PathIterator.SEG_MOVETO, PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO,PathIterator.SEG_CUBICTO and PathIterator.SEG_CLOSE)
      coords - the coordinates array as defined by PathIterator, but with coords[0] and coords[1] set to the X and Y coordinates respectively for the last PathIterator.SEG_MOVETO operation when the type is PathIterator.SEG_CLOSE
      Returns:
      the value of the X coordinate
      Throws:
      IllegalArgumentException - u is out of range or the type does not have a legal value
      ArrayIndexOutOfBoundsException - the array argument was two small
      NullPointerException - the array argument was null
    • getY

      public static double getY(double u, double x0, double y0, int type, double[] coords) throws IllegalArgumentException
      Compute the Y coordinate of a point on a path given path-segment parameters. When the type is PathIterator.SEG_MOVETO, x0 and y0 are ignored. When the type is PathIterator.SEG_CLOSE, the first two elements of coords must be set to the X and Y coordinate respectively for the point provided by most recent segment whose type is PathIterator.SEG_MOVETO.
      Parameters:
      u - the path-segment parameter in the range [0,1]
      x0 - the X coordinate of the point on the segment for u = 0
      y0 - the Y coordinate of the point on the segment for u = 0
      type - the segment type as defined by PathIterator (values may be PathIterator.SEG_MOVETO, PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, PathIterator.SEG_CUBICTO and PathIterator.SEG_CLOSE)
      coords - the coordinates array as defined by PathIterator, but with coords[0] and coords[1] set to the X and Y coordinates respectively for the last MOVETO operation when the type is PathIterator.SEG_CLOSE
      Returns:
      the value of the Y coordinate
      Throws:
      IllegalArgumentException - u is out of range or the type does not have a legal value
      ArrayIndexOutOfBoundsException - the array argument was two small
      NullPointerException - the array argument was null
    • dxDu

      public static double dxDu(double u, double x0, double y0, int type, double[] coords) throws IllegalArgumentException
      Compute dx/du given path-segment parameters. The type may not be PathIterator.SEG_MOVETO. When the type is PathIterator.SEG_CLOSE, the first two elements of coords must be set to the X and Y coordinate respectively for the point provided by most recent segment whose type is PathIterator.SEG_MOVETO.
      Parameters:
      u - the path-segment parameter in the range [0,1]
      x0 - the X coordinate of the point on the segment for u = 0
      y0 - the Y coordinate of the point on the segment for u = 0
      type - the segment type as defined by PathIterator (values may be PathIterator.SEG_MOVETO, PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, PathIterator.SEG_CUBICTO and PathIterator.SEG_CLOSE)
      coords - the coordinates array as defined by PathIterator, but with coords[0] and coords[1] set to the X and Y coordinates respectively for the last PathIterator.SEG_MOVETO operation when the type is PathIterator.SEG_CLOSE
      Returns:
      the value of dx/ds
      Throws:
      IllegalArgumentException - u is out of range or the type does not have a legal value
      ArrayIndexOutOfBoundsException - the array argument was two small
      NullPointerException - the array argument was null
    • dyDu

      public static double dyDu(double u, double x0, double y0, int type, double[] coords) throws IllegalArgumentException
      Compute dy/du given path-segment parameters. The type may not be PathIterator.SEG_MOVETO. When the type is PathIterator.SEG_CLOSE, the first two elements of coords must be set to the X and Y coordinate respectively for the point provided by most recent segment whose type is PathIterator.SEG_MOVETO.
      Parameters:
      u - the path-segment parameter in the range [0,1]
      x0 - the X coordinate of the point on the segment for u = 0
      y0 - the Y coordinate of the point on the segment for u = 0
      type - the segment type as defined by PathIterator (values may be PathIterator.SEG_MOVETO, PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, PathIterator.SEG_CUBICTO and PathIterator.SEG_CLOSE)
      coords - the coordinates array as defined by PathIterator, but with coords[0] and coords[1] set to the X and Y coordinates respectively for the last MOVETO operation when the type is PathIterator.SEG_CLOSE
      Returns:
      the value of dy/du
      Throws:
      IllegalArgumentException - u is out of range or the type does not have a legal value
      ArrayIndexOutOfBoundsException - the array argument was two small
      NullPointerException - the array argument was null
    • dsDu

      public static double dsDu(double u, double x0, double y0, int type, double[] coords) throws IllegalArgumentException
      Compute the derivative of the path length s with respect to the path's parameter u given path-segment parameters. The type may not be PathIterator.SEG_MOVETO. When the type is PathIterator.SEG_CLOSE, the first two elements of coords must be set to the X and Y coordinate respectively for the point provided by most recent segment whose type is PathIterator.SEG_MOVETO.
      Parameters:
      u - the path-segment parameter in the range [0,1]
      x0 - the X coordinate of the point on the segment for u = 0
      y0 - the Y coordinate of the point on the segment for u = 0
      type - the segment type as defined by PathIterator (values may be PathIterator.SEG_MOVETO, PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, PathIterator.SEG_CUBICTO and PathIterator.SEG_CLOSE)
      coords - the coordinates array as defined by PathIterator, but with coords[0] and coords[1] set to the X and Y coordinates respectively for the last PathIterator.SEG_MOVETO operation when the type is PathIterator.SEG_CLOSE
      Returns:
      the value of ds/du
      Throws:
      IllegalArgumentException - u is out of range or the type does not have a legal value
      ArrayIndexOutOfBoundsException - the array argument was two small
      NullPointerException - the array argument was null
    • d2xDu2

      public static double d2xDu2(double u, double x0, double y0, int type, double[] coords) throws IllegalArgumentException
      Compute the second derivative of x with respect to u given path-segment parameters. The type may not be PathIterator.SEG_MOVETO. When the type is PathIterator.SEG_CLOSE, the first two elements of coords must be set to the X and Y coordinate respectively for the point provided by most recent segment whose type is PathIterator.SEG_MOVETO.
      Parameters:
      u - the path-segment parameter in the range [0,1]
      x0 - the X coordinate of the point on the segment for u = 0
      y0 - the Y coordinate of the point on the segment for u = 0
      type - the segment type as defined by PathIterator (values may be PathIterator.SEG_MOVETO, PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, PathIterator.SEG_CUBICTO and PathIterator.SEG_CLOSE)
      coords - the coordinates array as defined by PathIterator, but with coords[0] and coords[1] set to the X and Y coordinates respectively for the last PathIterator.SEG_MOVETO operation when the type is PathIterator.SEG_CLOSE
      Returns:
      the value of 2x/du2;
      Throws:
      IllegalArgumentException - u is out of range or the type does not have a legal value
      ArrayIndexOutOfBoundsException - the array argument was two small
      NullPointerException - the array argument was null
    • d3xDu3

      public static double d3xDu3(double u, double x0, double y0, int type, double[] coords) throws IllegalArgumentException
      Compute the third derivative of x with respect to u given path-segment parameters. The type may not be PathIterator.SEG_MOVETO. When the type is PathIterator.SEG_CLOSE, the first two elements of coords must be set to the X and Y coordinate respectively for the point provided by most recent segment whose type is PathIterator.SEG_MOVETO.
      Parameters:
      u - the path-segment parameter in the range [0,1]
      x0 - the X coordinate of the point on the segment for u = 0
      y0 - the Y coordinate of the point on the segment for u = 0
      type - the segment type as defined by PathIterator (values may be PathIterator.SEG_MOVETO, PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, PathIterator.SEG_CUBICTO and PathIterator.SEG_CLOSE)
      coords - the coordinates array as defined by PathIterator, but with coords[0] and coords[1] set to the X and Y coordinates respectively for the last PathIterator.SEG_MOVETO operation when the type is PathIterator.SEG_CLOSE
      Returns:
      the value of 2x/du2;
      Throws:
      IllegalArgumentException - u is out of range or the type does not have a legal value
      ArrayIndexOutOfBoundsException - the array argument was two small
      NullPointerException - the array argument was null
    • d2yDu2

      public static double d2yDu2(double u, double x0, double y0, int type, double[] coords) throws IllegalArgumentException
      Compute the second derivative of y with respect to u given path-segment parameters. The type may not be PathIterator.SEG_MOVETO. When the type is PathIterator.SEG_CLOSE, the first two elements of coords must be set to the X and Y coordinate respectively for the point provided by most recent segment whose type is PathIterator.SEG_MOVETO.
      Parameters:
      u - the path-segment parameter in the range [0,1]
      x0 - the X coordinate of the point on the segment for u = 0
      y0 - the Y coordinate of the point on the segment for u = 0
      type - the segment type as defined by PathIterator (values may be PathIterator.SEG_MOVETO, PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, PathIterator.SEG_CUBICTO and PathIterator.SEG_CLOSE)
      coords - the coordinates array as defined by PathIterator, but with coords[0] and coords[1] set to the X and Y coordinates respectively for the last PathIterator.SEG_MOVETO operation when the type is PathIterator.SEG_CLOSE
      Returns:
      the value of d2y/du2;
      Throws:
      IllegalArgumentException - u is out of range or the type does not have a legal value
      ArrayIndexOutOfBoundsException - the array argument was two small
      NullPointerException - the array argument was null
    • d3yDu3

      public static double d3yDu3(double u, double x0, double y0, int type, double[] coords) throws IllegalArgumentException
      Compute the third derivative of y with respect to u given path-segment parameters. The type may not be PathIterator.SEG_MOVETO. When the type is PathIterator.SEG_CLOSE, the first two elements of coords must be set to the X and Y coordinate respectively for the point provided by most recent segment whose type is PathIterator.SEG_MOVETO.
      Parameters:
      u - the path-segment parameter in the range [0,1]
      x0 - the X coordinate of the point on the segment for u = 0
      y0 - the Y coordinate of the point on the segment for u = 0
      type - the segment type as defined by PathIterator (values may be PathIterator.SEG_MOVETO, PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, PathIterator.SEG_CUBICTO and PathIterator.SEG_CLOSE)
      coords - the coordinates array as defined by PathIterator, but with coords[0] and coords[1] set to the X and Y coordinates respectively for the last PathIterator.SEG_MOVETO operation when the type is PathIterator.SEG_CLOSE
      Returns:
      the value of d3y/du3;
      Throws:
      IllegalArgumentException - u is out of range or the type does not have a legal value
      ArrayIndexOutOfBoundsException - the array argument was two small
      NullPointerException - the array argument was null
    • d2sDu2

      public static double d2sDu2(double u, double x0, double y0, int type, double[] coords) throws IllegalArgumentException
      Compute the second derivative of the path length s with respect to u given path-segment parameters. When the type is PathIterator.SEG_CLOSE, the first two elements of the fifth argument (coords) must be set to the x and y coordinate respectively for the point provided by most recent segment whose type is PathIterator.SEG_MOVETO.

      The returned value will be Double.NaN in cases where division by zero would occur, such as when the initial point for a segment and the control points and final point given by the array argument are identical. The most likely case is when the type is PathIterator.SEG_CLOSE.

      Parameters:
      u - the path-segment parameter in the range [0,1]
      x0 - the X coordinate of the point on the segment for u = 0
      y0 - the Y coordinate of the point on the segment for u = 0
      type - the segment type as defined by PathIterator (values may be PathIterator.SEG_MOVETO, PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, PathIterator.SEG_CUBICTO and PathIterator.SEG_CLOSE)
      coords - the coordinates array as defined by PathIterator, but with coords[0] and coords[1] set to the X and Y coordinates respectively for the last PathIterator.SEG_MOVETO operation when the type is PathIterator.SEG_CLOSE
      Returns:
      the value of d2s/du2; Double.NaN if not defined but zero if the type is PathIterator.SEG_MOVETO
      Throws:
      IllegalArgumentException - u is out of range or the type does not have a legal value
      ArrayIndexOutOfBoundsException - the array argument was two small
      NullPointerException - the array argument was null
      See Also:
    • curvature

      public static double curvature(double u, double x0, double y0, int type, double[] coords) throws IllegalArgumentException
      Compute the signed curvature given path-segment parameters. The type may not be PathIterator.SEG_MOVETO. When the type is PathIterator.SEG_CLOSE, the first two elements of coords must be set to the X and Y coordinate respectively for the point provided by most recent segment whose type is PathIterator.SEG_MOVETO. A positive curvature corresponds to a rotation from the positive X axis towards the positive Y axis for an angular distance of 90 degrees. Similarly a negative curvature corresponds to a rotation from the positive Y axis towards the positive X axis for an angular distance of 90 degrees.

      If an instance of Path2DInfo.Entry entry is available, it is significantly more efficient to call entry.getData().curvature(new UValues(u)) instead of this method (a timing test showed an improvement of more than a factor of 10).

      Parameters:
      u - the path-segment parameter in the range [0,1]
      x0 - the X coordinate of the point on the segment for u = 0
      y0 - the Y coordinate of the point on the segment for u = 0
      type - the segment type as defined by PathIterator (values may be PathIterator.SEG_MOVETO, PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, PathIterator.SEG_CUBICTO and PathIterator.SEG_CLOSE)
      coords - the coordinates array as defined by PathIterator, but with coords[0] and coords[1] set to the X and Y coordinates respectively for the last PathIterator.SEG_MOVETO operation when the type is PathIterator.SEG_CLOSE
      Returns:
      the curvature with positive values indicating that the tangent vector rotates counterclockwise as the path parameter increases; Double.NaN if not defined (this may happen if a line segment has zero length)
      Throws:
      IllegalArgumentException - u is out of range or the type does not have a legal value
      ArrayIndexOutOfBoundsException - the array argument was two small
      NullPointerException - the array argument was null
    • curvatureExists

      public static boolean curvatureExists(double u, double x0, double y0, int type, double[] coords) throws IllegalArgumentException, NullPointerException, IndexOutOfBoundsException
      Determine if the arguments allow the curvature to be computed. The curvature cannot be computed when the type is PathIterator.SEG_MOVETO or when the control points provided by the array match the initial values x0 and y0.
      Parameters:
      u - the path-segment parameter in the range [0,1]
      x0 - the X coordinate of the point on the segment for u = 0
      y0 - the Y coordinate of the point on the segment for u = 0
      type - the segment type as defined by PathIterator (values may be PathIterator.SEG_MOVETO, PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, PathIterator.SEG_CUBICTO and PathIterator.SEG_CLOSE)
      coords - the coordinates array as defined by PathIterator, but with coords[0] and coords[1] set to the X and Y coordinates respectively for the last MOVETO operation when the type is PathIterator.SEG_CLOSE
      Returns:
      true if the curvature exists for the path parameter; false otherwise.
      Throws:
      IllegalArgumentException - u is out of range or the type does not have a legal value
      NullPointerException
      IndexOutOfBoundsException
    • getTangent

      public static boolean getTangent(double u, double[] array, int offset, double x0, double y0, int type, double[] coords)
      Get the tangent vector for a specified value of the path parameter and an output-array offset. If the tangent vector does not exist (e.g., the length of the line does not vary with the path parameter), the tangent vector will be set to zero. The tangent vector will have unit length if it is not zero.
      Parameters:
      u - the path-segment parameter in the range [0,1]
      array - an array of length no less than 2 used to store the tangent vector, with array[offset] containing the tangent vector's X component and array[offset+1] containing the tangent vector's Y component
      offset - the index into the array at which to store the tangent vector
      x0 - the X coordinate of the point on the segment for u = 0
      y0 - the Y coordinate of the point on the segment for u = 0
      type - the segment type as defined by PathIterator (values may be PathIterator.SEG_MOVETO, PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, PathIterator.SEG_CUBICTO and PathIterator.SEG_CLOSE)
      coords - the coordinates array as defined by PathIterator, but with coords[0] and coords[1] set to the X and Y coordinates respectively for the last MOVETO operation when the type is PathIterator.SEG_CLOSE
      Returns:
      true if the tangent vector exists; false if the tangent vector does not exist
    • getNormal

      public static boolean getNormal(double u, double[] array, int offset, double x0, double y0, int type, double[] coords)
      Get the normal vector for a given value of the path parameter and an offset for the array storing the normal vector. The normal vector N is a vector of unit length, perpendicular to the tangent vector, and oriented so that d2r/ds2 = κN where κ is the (signed) curvature. If the normal vector does not exist (e.g., the length of the line does not vary with the path parameter), the normal vector will be set to zero.

      Note: the use of the signed curvature results in the normal vector always pointing in the counter-clockwise direction (i.e., a rotating the X axis towards the Y axis). This allows a normal vector exist for straight-line segments. A different definition is used for 3D paths.

      Parameters:
      u - the path-segment parameter in the range [0,1]
      array - an array of length no less than 2 used to store the normal vector, with array[offset] containing the normal vector's X component and array[offset+1] containing the normal vector's Y component
      offset - the index into the array at which to store the normal vector
      x0 - the X coordinate of the point on the segment for u = 0
      y0 - the Y coordinate of the point on the segment for u = 0
      type - the segment type as defined by PathIterator (values may be PathIterator.SEG_MOVETO, PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, PathIterator.SEG_CUBICTO and PathIterator.SEG_CLOSE)
      coords - the coordinates array as defined by PathIterator, but with coords[0] and coords[1] set to the X and Y coordinates respectively for the last MOVETO operation when the type is PathIterator.SEG_CLOSE
      Returns:
      true if the normal vector exists; false if the normal vector does not exist
    • getStart

      public static Point2D getStart(Path2D path) throws NullPointerException, IllegalArgumentException
      Get the starting point along a path. To get the last point on a path, use Path2D.getCurrentPoint().
      Parameters:
      path - the path
      Returns:
      the first point on the path; null if the path is empty
      Throws:
      NullPointerException - the path is null
      IllegalArgumentException - the path is ill formed (All paths must start with a segment whose type is PathIterator.SEG_MOVETO.)
      See Also:
    • getTangent

      public static boolean getTangent(Path2D path, Path2DInfo.Location location, double[] array, int offset) throws IllegalArgumentException, NullPointerException
      Get the tangent vector at the start or end of a path.
      Parameters:
      path - the path
      location - Path2DInfo.Location.START if the tangent vector is computed at the start of the path; Path2DInfo.Location.ENDif the tangent vector is computed at the end of the path.
      array - an array used to store the tangent vector
      offset - the offset into the array such that the X component of the tangent vector is array[offset] and the Y component of the tangent vector is array[offset+1]
      Returns:
      true if the tangent vector exists; false otherwise
      Throws:
      IllegalArgumentException - the path is not a valid path or the array and offset are not suitable for storing the tangent vector
      NullPointerException - an argument (path or array) is null
    • getNormal

      public static boolean getNormal(Path2D path, Path2DInfo.Location location, double[] array, int offset)
      Get the normal vector at the start or end of a path.
      Parameters:
      path - the path
      location - Path2DInfo.Location.START if the normal vector is computed at the start of the path; Path2DInfo.Location.ENDif the normal vector is computed at the end of the path.
      array - an array used to store the normal vector
      offset - the offset into the array such that the X component of the normal vector is array[offset] and the Y component of the normal vector is array[offset+1]
      Returns:
      true if the tangent vector exists; false otherwise
      Throws:
      IllegalArgumentException - the path is not a valid path or the array and offset are not suitable for storing the normal vector
      NullPointerException - an argument (path or array) is null
    • getTypeString

      public static String getTypeString(int type)
      Get the type of a path-iterator item, formatted as a string
      Parameters:
      type - the type of a path-iterator segment: either PathIterator.SEG_MOVETO, PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, PathIterator.SEG_CUBICTO, or PathIterator.SEG_CLOSE
      Returns:
      a string describing the type
    • pathLength

      public static double pathLength(Shape path)
      Compute the length of a path or the length of an outline of a shape. This is the sum of the the lengths of all the path or outline segments. A shape's outline may pass through the shape, so this method does not reliably compute the circumference of a shape.
      Parameters:
      path - the path
      Returns:
      the path length
    • pathLength

      public static double pathLength(Shape path, AffineTransform at)
      Compute the length of a path or the length of an outline of a shape, modified by an affine transform. This is the sum of the the lengths of all the path or outline segments. A shape's outline may pass through the shape, so this method does not reliably compute the circumference of a shape.
      Parameters:
      path - the path
      at - the affine transform; null if none is to be used
      Returns:
      the path length
    • pathLength

      public static double pathLength(Shape path, int start, int end)
      Compute the length of a path or the length of an outline of a shape for a given range of path/outline segments. This is the sum of the the lengths of all the path segments whose indices are in the interval [start, end) with start < end. Some of the segments for a shape may pass though the interior of the shape.
      Parameters:
      path - the path
      start - the starting index
      end - the index just past the last index counted
      Returns:
      the length of the portion of a path in the specified interval
    • pathLength

      public static double pathLength(Shape path, AffineTransform at, int start, int end)
      Compute the length of a path or the length of an outline of a shape for a given range of path/outline segments, modified by an affine transform. This is the sum of the the lengths of all the path segments whose indices are in the interval [start, end) with start < end. Some of the segments for a shape may pass though the interior of the shape.
      Parameters:
      path - the path
      at - the affine transform; null if none is to be used
      start - the starting index
      end - the index just past the last index counted
      Returns:
      the length of the portion of a path in the specified interval
    • segmentLength

      public static double segmentLength(int type, double x0, double y0, double[] coords)
      Compute the length of a segment given parameters describing it.
      Parameters:
      x0 - the X coordinate of the point on the segment for u = 0
      y0 - the Y coordinate of the point on the segment for u = 0
      type - the segment type as defined by PathIterator (values may be PathIterator.SEG_MOVETO, PathIterator.SEG_LINETO, PathIterator.SEG_QUADTO, PathIterator.SEG_CUBICTO and PathIterator.SEG_CLOSE)
      coords - the coordinates array as defined by PathIterator, but with coords[0] and coords[1] set to the X and Y coordinates respectively for the last MOVETO operation when the type is PathIterator.SEG_CLOSE
      Returns:
      the segment length
    • segmentLength

      public static double segmentLength(Shape p, int segment)
      Get the length of the ith segment of a path or of a shape's outline. For a shape, some of the segments may pass through the interior of the shape.
      Parameters:
      p - the path or shape
      segment - the segment number from 0 up to but not including the number of segments
      Returns:
      the segment length
    • getEntries

      public static List<Path2DInfo.Entry> getEntries(Shape p)
      Get a list of entries describing a path's segments or those for the outline of a shape.
      Parameters:
      p - the path or shape
      Returns:
      the list of entries
    • getEntries

      public static List<Path2DInfo.Entry> getEntries(Shape p, AffineTransform at)
      Get a list of entries describing a path's segments or those for the outline of a shape, modified by an affine transform.
      Parameters:
      p - the path or shape
      at - the affine transform; null if none is to be used
      Returns:
      the list of entries
    • isCounterclockwise

      public static boolean isCounterclockwise(Path2D path) throws IllegalArgumentException
      Determine if a path is oriented counterclockwise when traversed in the direction of an increasing path parameter. Paths must start with a PathIterator.SEG_MOVETO segment and end with a PathIterator.SEG_CLOSE segment, with no other PathIterator.SEG_CLOSE segments along the path, and a path should not intersect itself. Self-intersecting paths are not detected, with the exception of multiple loops whose signed areas sum to zero, where a signed area is positive for counterclockwise loops and negative for clockwise loops. The signed area is used to distinguish clockwise and counterclockwise paths

      The terms clockwise and counterclockwise assume the normal mathematical convention in which the positive X axis points right and the positive Y axis points left. This is the opposite of the convention used in Java's AWT classes in which the positive Y axis points downwards.

      Parameters:
      path - the path
      Returns:
      true if the path is counterclockwise; false if it is clockwise
      Throws:
      IllegalArgumentException - the path is not a simple loop (a path terminated by a PathIterator.SEG_CLOSE segment, with no other PathIterator.SEG_CLOSE segments along the path) or the region enclosed by the path has zero area or the path crosses itself (in such a way that the area computed is zero)
    • isClockwise

      public static boolean isClockwise(Path2D path) throws IllegalArgumentException
      Determine if a path is oriented clockwise when traversed in the direction of an increasing path parameter. Paths must start with a PathIterator.SEG_MOVETO segment and end with a PathIterator.SEG_CLOSE segment, with no other PathIterator.SEG_CLOSE segments along the path, and a path should not intersect itself. Self-intersecting paths are not detected, with the exception of multiple loops whose signed areas sum to zero, where a signed area is positive for counterclockwise loops and negative for clockwise loops. The signed area is used to distinguish clockwise and counterclockwise paths

      The terms clockwise and counterclockwise assume the normal mathematical convention in which the positive X axis points right and the positive Y axis points left. This is the opposite of the convention used in Java's AWT classes in which the positive Y axis points downwards.

      Parameters:
      path - the path
      Returns:
      true if the path is clockwise; false if it is counterclockwise
      Throws:
      IllegalArgumentException - the path is not a simple loop (a path terminated by a PathIterator.SEG_CLOSE segment, with no other PathIterator.SEG_CLOSE segments along the path) or the region enclosed by the path has zero area or the path crosses itself (in such a way that the area computed is zero)
    • centerOfMassOf

      public static Point2D centerOfMassOf(Shape shape)
      Compute the center of mass of a shape, assuming the area has a uniform density.

      Note: the algorithm used is fast, but will lose accuracy if the area is very small compared to the area of the shape's bounding box.

      Parameters:
      shape - the shape
      Returns:
      the center of mass
    • centerOfMassOf

      public static Point2D centerOfMassOf(Shape shape, AffineTransform af)
      Compute the center of mass of a shape, optionally modified by an affine transformation assuming the area has a uniform density.

      Note: the algorithm used is fast, but will lose accuracy if the area is very small compared to the area of the shape's bounding box.

      Parameters:
      shape - the shape
      af - the affine transformation
      Returns:
      the center of mass
    • momentsOf

      public static double[][] momentsOf(Shape shape)
      Get the moments about the center of mass for the area inside a shape. For a shape S with an area A,
      • moments[0][0] = $\frac1A \int_S x^2 dA$.
      • moments[0][1] = $\frac1A \int_S xy dA$.
      • moments[1][0] = $\frac1A \int_S xy dA$.
      • moments[1][1] = $\frac1A \int_S y^2 dA$.

      Note: the moment of inertia tensor has different values. Assuming that the area has a Z value of 0 and that the density (mass per unit area) is 1.0/A, one obtains

      • Ixx = moments[1][1].
      • Ixy = - moments[0][1].
      • Ixy = - moments[1][0].
      • Iyy = moments[0][0].
      • Izz = moments[0][0] + moments[1][1]
      Any other component with a 'z' index is 0.
      Parameters:
      shape - the shape
      Returns:
      a matrix containing the moments
    • momentsOf

      public static double[][] momentsOf(Shape shape, AffineTransform af)
      Get the moments for the area inside a shape modified by an affine transformation and about the center of mass of the modified shape. If S is the shape after applying an affine transformation an A is the corresponding area,
      • moments[0][0] = $\frac1A \int_S x^2 dA$.
      • moments[0][1] = $\frac1A \int_S xy dA$.
      • moments[1][0] = $\frac1A \int_S xy dA$.
      • moments[1][1] = $\frac1A \int_S y^2 dA$.

      Note: the moment of inertia tensor has different values. Assuming that the area has a Z value of 0 and that the density (mass per unit area) is 1.0, one obtains

      • Ixx = moments[1][1].
      • Ixy = - moments[0][1].
      • Ixy = - moments[1][0].
      • Iyy = moments[0][0].
      • Izz = moments[0][0] + moments[1][1]
      Any other component with a 'z' index is 0.

      Note: the algorithm used is fast, but will lose accuracy if the area is very small compared to the area of the shape's bounding box.

      Parameters:
      shape - the shape
      af - the affine transform
      Returns:
      a matrix containing the moments
    • momentsOf

      public static double[][] momentsOf(Point2D center, Shape shape)
      Get the moments for the area inside a shape about a reference point. For a reference point (xr, yr) and a shape S with area A,
      • moments[0][0] = $\frac1A \int_S (x -x_r)^2 dA$.
      • moments[0][1] = $\frac1A \int_S (x-x_r)(y-y_r) dA$.
      • moments[1][0] = $\frac1A \int_S (x-x_r)(y-y_r) dA$.
      • moments[1][1] = $\frac1A \int_S (y-y_r)^2 dA$.

      Note: the moment of inertia tensor has different values. Assuming that the area has a Z value of 0 and that the density (mass per unit area) is 1.0, one obtains

      • Ixx = moments[1][1].
      • Ixy = - moments[0][1].
      • Ixy = - moments[1][0].
      • Iyy = moments[0][0].
      • Izz = moments[0][0] + moments[1][1]
      Any other component with a 'z' index is 0.

      Note: the first argument is a point because momentsOf(Shape,AffineTransform) can have a null second argument, so putting the point first prevents a compile-time ambiguity for cases where the AffineTransform should be null.

      Note: the algorithm used is fast, but will lose accuracy if the area is very small compared to the area of the shape's bounding box.

      Parameters:
      center - the point about which the moments are computed
      shape - the shape
      Returns:
      a matrix containing the moments
    • momentsOf

      public static double[][] momentsOf(Point2D center, Shape shape, AffineTransform af)
      Get the moments for the area inside a shape about a reference point after applying an affine transform to both. For a reference point (xr, yr) given a transformed shape S whose area is A,
      • moments[0][0] = $\frac1A \int_S (x -x_r)^2 dA$.
      • moments[0][1] = $\frac1A \int_S (x-x_r)(y-y_r) dA$.
      • moments[1][0] = $\frac1A \int_S (x-x_r)(y-y_r) dA$.
      • moments[1][1] = $\frac1A \int_S (y-y_r)^2 dA$.

      Note: the moment of inertia tensor has different values. Assuming that the area has a Z value of 0 and that the density (mass per unit area) is 1.0, one obtains

      • Ixx = moments[1][1].
      • Ixy = - moments[0][1].
      • Ixy = - moments[1][0].
      • Iyy = moments[0][0].
      • Izz = moments[0][0] + moments[1][1]
      Any other component with a 'z' index is 0.

      Note: the first argument is a point because momentsOf(Shape,AffineTransform) can have a null second argument, so putting the point first prevents a compile-time ambiguity for cases where the AffineTransform should be null.

      Note: the algorithm used is fast, but will lose accuracy if the area is very small compared to the area of the shape's bounding box.

      Parameters:
      center - the point about which the moments are computed
      shape - the shape
      af - the affine transform to apply to the shape and the center point
      Returns:
      a matrix containing the moments
    • toMomentsOfInertia

      public static double[][] toMomentsOfInertia(double[][] moments)
      Convert moments to moments of inertia. This conversion is for the case where the shape whose moments were calculated lies in the X-Y plane. For a moments matrix M, the value returned is the matrix $$ \left(\begin{array}{ccc} M_{11} & -M_{01} & 0 \\ -M_{10} & M_{00} & 0 \\ 0 & 0 & (M_{00} - M_{11}) \end{array}\right)$$ To compute the principal moments of inertia and their corresponding axes, use SurfaceOps.principalMoments(double[][]) and SurfaceOps.principalAxes(double[][]).
      Parameters:
      moments - the 2-by-2 moments matrix
      Returns:
      the 3-by-3 moments of inertia matrix if the area enclosed has a uniform surface density with a total mass of 1
    • principalMoments

      public static double[] principalMoments(double[][] moments)
      Find the principle moments of a shape given its moments. The array returned contains the moments sorted so that the smallest moment appears first. The argument array can be computed from a shape by calling momentsOf(Shape) or momentsOf(Shape, AffineTransform).

      The principal moments are the eigenvalues of the moments matrix. For the special case of a 2x2 matrix, an easily computed solution can be found at this web page.

      Parameters:
      moments - the shape's moments.
      Returns:
      the principal moments
    • principalAxes

      public static double[][] principalAxes(double[][] moments)
      Compute the principal axes corresponding a moments matrix. The moments matrix can be computed from a shape by calling the method momentsOf(Shape) or by calling the method momentsOf(Shape, AffineTransform). The method principalMoments(double[][]) can be used to compute the principal moments given a moments array. The return value for principalAxes is a two dimensional array. If the array returned is stored as pmatrix, then pmatrix[i] is an array containing the principal axis corresponding to the ith principal moment. Each principal axis vector contains its X component followed by its Y component and is normalized so its length is 1.0.

      The principal axes are actually the eigenvectors of the moments matrix provided as this method's first argument. In addition, the eigenvector at index 1 points counterclockwise from the one at index 0, assuming the convention in which the positive Y axis is counterclockwise from the positive X axis. For the special case of a 2x2 matrix, an easily computed solution to the eigenvalue problem can be found at this web page.

      Parameters:
      moments - the moments
      Returns:
      an array of vectors, each providing an axis.
    • areaOf

      public static double areaOf(Shape shape)
      Compute the area of a shape. Shapes will be converted to instance of Area, and as a result, shapes described by an open, continuous curve will effectively be closed with a line connecting the curve's end points. The area is that of the set of points within the boundary of the shape. The boundary of the shape is determined by a PathIterator that represents the boundary as a series of segments that are either straight lines, quadratic Bézier curves, or cubic Bézier curves. This is true for all shapes including ones representing ellipses (circles are a special case) and arcs. For these classes, the Java class library provides enough accuracy so that the objects look right. For a circle of unit radius, the area for an Ellipse2D differs from that of a true circle by less than 3 parts in 10,000.

      Accuracy is set by the floating-point representation - the algorithm used is exact. Time complexity is linear in the number of path segments for the shape's path iterator when the shape is an instance of Area. For any other class that implements the Shape interface, the shape is first used to create an instance of Area; however, the time complexity for this operation is not specified in the Java documentation.

      If the shape's path iterator has a winding rule of PathIterator.WIND_NON_ZERO, and one counterclockwise path component is inside another counterclockwise path component, the conversion to Area will result in an area consisting of the union of the two path components, and the inner path component will not appear in the area's iterator. When using this method, one should be careful about how shapes are represented and how winding rules affect the points that are considered to be inside or outside a shape.

      Parameters:
      shape - the shape
      Returns:
      the area of the shape
    • areaOf

      public static double areaOf(Shape shape, AffineTransform at)
      Compute the area of a shape modified by an affine transformation. Shapes will be converted to instance of Area, and as a result, shapes described by an open, continuous curve will effectively be closed with a line connecting the curve's end points. The area is that of the set of points within the boundary of the shape. The boundary of the shape is determined by a PathIterator that represents the boundary as a series of segments that are either straight lines, quadratic Bézier curves, or cubic Bézier curves. This is true for all shapes including ones representing ellipses (circles are a special case) and arcs. For these classes, the Java class library provides enough accuracy so that the objects look right. For a circle of unit radius, the area for an Ellipse2D differs from that of a true circle by less than 3 parts in 10,000.

      Accuracy is set by the floating-point representation - the algorithm used is exact. Time complexity is linear in the number of path segments for the shape's path iterator when the shape is an instance of Area. For any other class that implements the Shape interface, the shape is first used to create an instance of Area; however the time complexity for this operation is not specified in the Java documentation.

      If the shape's path iterator has a winding rule of PathIterator.WIND_NON_ZERO, and one counterclockwise path component is inside another counterclockwise path component, the conversion to Area will result in an area consisting of the union of the two path components, and the inner path component will not appear in the area's iterator. When using this method, one should be careful about how shapes are represented and how winding rules affect the points that are considered to be inside or outside a shape.

      Parameters:
      shape - the shape
      at - the affine transform to modify the shape; null if none is to be used
      Returns:
      the area of the shape
    • areaOf

      public static double areaOf(PathIterator pi) throws IllegalArgumentException
      Compute the area of a shape specified by a path iterator, using the differential form xdy - ydx. The winding rule for the path iterator must be PathIterator.WIND_NON_ZERO. It is the caller's responsibility to ensure the following:
      • the winding rule for the path iterator is PathIterator.WIND_NON_ZERO.
      • each subpath is closed.
      • subpaths do not intersect.
      • a subpath does not cross itself.
      • The angular direction (clockwise versus counterclockwise) are opposite for holes than for outer boundaries.
      Methods that take a Shape as an argument will automatically ensure that these constraints are met (perhaps by creating an Area). This method is provided for cases where the computation must be as fast as possible. The path iterator will be modified by this method.

      Accuracy is set by the floating-point representation - the algorithm used is exact. Time complexity is linear in the number of path segments.

      Note: the path integrals of the forms (x/2)dy-(y/2)ydx, xdy, and -ydx produce the same values when evaluated exactly. The values may, however, differ due to floating point accuracy.

      Parameters:
      pi - a path iterator.
      Returns:
      the area of the shape specified by the path iterator pi
      Throws:
      IllegalArgumentException - the winding rule is not correct.
      See Also:
    • areaOf

      public static double areaOf(PathIterator pi, boolean xdy) throws IllegalArgumentException
      Compute the area of a shape specified by a path iterator, using the differential form xdy or -ydx. The winding rule for the path iterator must be PathIterator.WIND_NON_ZERO. It is the caller's responsibility to ensure the following:
      • the winding rule for the path iterator is PathIterator.WIND_NON_ZERO.
      • each subpath is closed.
      • subpaths do not intersect.
      • a subpath does not cross itself.
      • The angular direction (clockwise versus counterclockwise) are opposite for holes than for outer boundaries.
      Methods that take a Shape as an argument will automatically ensure that these constraints are met (perhaps by creating an Area). This method is provided for cases where the computation must be as fast as possible. The path iterator will be modified by this method.

      Accuracy is set by the floating-point representation - the algorithm used is exact. Time complexity is linear in the number of path segments.

      Note: the path integrals of the forms (x/2)dy-(y/2)ydx, xdy, and -ydx produce the same values when evaluated exactly. The values may, however, differ due to floating point accuracy. Using this method twice, with different values of the argumnet xdy, provides a rough estimate of numerical accuracy. The execution time for this method is slightly faster than that provided by areaOf(PathIterator).

      Parameters:
      pi - a path iterator.
      xdy - true if the differential form is xdy; false if the differential form is -ydx
      Returns:
      the area of the shape specified by the path iterator pi
      Throws:
      IllegalArgumentException - the winding rule is not correct.
      See Also:
    • areaOf

      public static double areaOf(PathIterator pi, AffineTransform at) throws IllegalArgumentException
      Compute the area of a shape specified by a path iterator and affine transformation.

      The winding rule for the path iterator must be PathIterator.WIND_NON_ZERO. It is the caller's responsibility to ensure the following:

      • the winding rule for the path iterator is PathIterator.WIND_NON_ZERO.
      • each subpath is closed.
      • subpaths do not intersect.
      • a subpath does not cross itself.
      • The angular direction (clockwise versus counterclockwise) are opposite for holes than for outer boundaries.
      Methods that take a Shape as an argument will automatically ensure that these constraints are met (perhaps by creating an Area). This method is provided for cases where the computation must be as fast as possible. The path iterator will be modified by this method.

      Accuracy is set by the floating-point representation - the algorithm used is exact. Time complexity is linear in the number of path segments.

      Parameters:
      pi - a path iterator.
      at - an affine transform to apply to each point provided by the path iterator pi; null if none is used
      Returns:
      the area of the shape specified by the path iterator pi
      Throws:
      IllegalArgumentException - the winding rule is not correct.
    • circumferenceOf

      public static double circumferenceOf(Shape shape)
      Compute the circumference of a shape. The circumference is defined as the length of the boundary of a shape (i.e., if the shape contains a hole, the circumference of the hole is included). The boundary of the shape is determined by a PathIterator that represents the boundary as a series of segments that are either straight lines, quadratic Bézier curves, or cubic Bézier curves. This is true for all shapes including ones representing ellipses (circles are a special case) and arcs. For these classes, the Java class library provides enough accuracy so that the objects look right. For a circle of unit radius, the circumference for an Ellipse2D differs from that of a true circle by less than 2 parts in 10,000.

      A Shape that is not an Area is first converted to an Area. This will result in open, continuous paths being closed by adding a straight line between the path's end points. An Area is required to be described by non-overlapping, closed paths using the winding rule WIND_NON_ZERO. The documentation for Area states that "The interiors of the individual stored sub-paths are all non-empty and non-overlapping. Paths are decomposed during construction into separate component non-overlapping parts, empty pieces of the path are discarded, and then these non-empty and non-overlapping properties are maintained through all subsequent constructive-area-geometry operations. Outlines of different component sub-paths may touch each other, as long as they do not cross so that their enclosed areas overlap." With the double-precision version of various objects, tests produced subpaths that touch each other at a single point, but not cases in which a line segment was shared. If a single-precision object was created, however, subpaths may have a curve in common. For example, if a path p consists of two aligned rectangles with a gap between them of 0.0000000001, The path s defined by

      Path2D s = new Path2D.Float(new Area(p));
      will include two path segments, one from each rectangle, with the same end points. For such corner cases, the circumference returned by this method is not what one would expect when viewing a filled path.
      Parameters:
      shape - the shape
      Returns:
      the circumference
    • circumferenceOf

      public static double circumferenceOf(Shape shape, AffineTransform at)
      Compute the circumference of a shape modified by an affine transform. The circumference is defined as the length of the boundary of a shape (i.e., if the shape contains a hole, the circumference of the hole is included). The boundary of the shape is determined by a PathIterator that represents the boundary as a series of segments that are either straight lines, quadratic Bézier curves, or cubic Bézier curves. This is true for all shapes including ones representing ellipses (circles are a special case) and arcs. For these classes, the Java class library provides enough accuracy so that the objects look right. For a circle of unit radius, the circumference for an Ellipse2D differs from that of a true circle by less than 2 parts in 10,000.

      A Shape that is not an Area is first converted to an Area. This will result in open, continuous paths being closed by adding a straight line between the path's end points. An Area is required to be described by non-overlapping, closed paths using the winding rule WIND_NON_ZERO. The documentation for Area states that "The interiors of the individual stored sub-paths are all non-empty and non-overlapping. Paths are decomposed during construction into separate component non-overlapping parts, empty pieces of the path are discarded, and then these non-empty and non-overlapping properties are maintained through all subsequent constructive-area-geometry operations. Outlines of different component sub-paths may touch each other, as long as they do not cross so that their enclosed areas overlap." With the double-precision version of various objects, tests produced subpaths that touch each other at a single point, but not cases in which a line segment was shared. If a single-precision object was created, however, subpaths may have a curve in common. For example, if a path p consists of two aligned rectangles with a gap between them of 0.0000000001, The path s defined by

      Path2D s = new Path2D.Float(new Area(p));
      will include two path segments, one from each rectangle, with the same end points. For such corner cases, the circumference returned by this method is not what one would expect when viewing a filled path.
      Parameters:
      shape - the shape
      at - the affine transform; null if there is none
      Returns:
      the circumference
    • printSegments

      public static void printSegments(Shape s)
      Print information about the segments that make up a path, or the outline of a shape, to the standard output. Entry i contains the X and Y coordinate when the parameter is equal to i, followed by control points, the last of which is the coordinate when the parameter is i+1.
      Parameters:
      s - the shape or path
    • printSegments

      public static void printSegments(Appendable appendable, Shape s)
      Print information about the segments that make up a path or an outline of a shape. Entry i contains the X and Y coordinate when the parameter is equal to i, followed by control points, the last of which is the coordinate when the parameter is i+1.
      Parameters:
      appendable - an Appendable on which to print
      s - the shape or path
    • printSegments

      public static void printSegments(String prefix, Appendable appendable, Shape s)
      Print information about the segments that make up a path or the outline of a shape, adding a prefix. Entry i contains the X and Y coordinate when the parameter is equal to i, followed by control points, the last of which is the coordinate when the parameter is i+1.
      Parameters:
      prefix - a prefix to print at the start of each line (null implies an empty string)
      appendable - the appendable for output
      s - the shape or path
    • getCPoints

      public static List<SplinePathBuilder.CPoint> getCPoints(Path2D path)
      Get a list of CPoint objects that can be used to configure a spline-path builder. The list can be modified by using the methods AbstractSplinePathBuilder.modifyCPoints(List,boolean,AffineTransform) or AbstractSplinePathBuilder.modifyCPoints(SplinePathBuilder.CPoint[],boolean,AffineTransform) if the modification consists of reversing the order of entries in the list or applying an affine transformation to the control points.
      Parameters:
      path - the path
      Returns:
      a list of CPoint objects specifying the control points for a path
    • shiftClosedPath

      public static Path2D shiftClosedPath(Path2D path, double x, double y)
      Find the first closed component of a path that goes through a point (x, y) and shift that path component so it starts at (x, y). The point (x, y) must be the last point in a segment (including a MOVE_TO segment).
      Parameters:
      path - the path
      x - the X coordinate of a point on the path
      y - the Y coordinate of a point on the path
      Returns:
      the patch component going through (x, y), with its segments shifted cyclically so that the returned path starts at the point (x, y).
      Throws:
      IllegalArgumentException - the path contains a control point other than PathIterator.SEG_MOVETO immediately after PathIterator.SEG_CLOSE
    • numberOfDrawableSegments

      public static int numberOfDrawableSegments(Path2D path)
      Count the number of segments in the first continuous portion of a path that are Drawable. Drawable segments exclude PathIterator.SEG_MOVETO segments and PathIterator.SEG_CLOSE segments whose current point is the same as that of a previous PathIterator.SEG_MOVETO segment. The test ignores any segments after a second PathIterator.SEG_MOVE or a first PathIterator.SEG_CLOSE. If the last point is the segment preceding a PathIterator.SEG_CLOSE segment is equal to t he initial segment (whose type is first PathIterator.SEG_MOVETO), the terminating PathIterator.SEG_CLOSE segment is not included in the count. For an open path, the number of drawable segments is one less than the number of drawable knots. For a closed path, the number of drawable knots and the number of drawable segments are the same.
      Parameters:
      path - the path
      Returns:
      the number of drawable segments
      Throws:
      IllegalStateException - if the path does not start with a segment whose type is PathIterator.SEG_MOVE.
    • numberOfDrawableKnots

      public static int numberOfDrawableKnots(Path2D path)
      Count the number of knots in the first continuous portion of a path that are Drawable. Knots are defined as those control points that are not intermediate control points. For a closed path, if the end of the preceding segment is the point corresponding to the last PathIterator.SEG_MOVETO, that point is ignored. The test ignores any segments after a second PathIterator.SEG_MOVE or a first PathIterator.SEG_CLOSE. If the last point is the segment preceding a PathIterator.SEG_CLOSE segment is equal to t he initial segment (whose type is first PathIterator.SEG_MOVETO), the terminating PathIterator.SEG_CLOSE segment is not included in the count. For an open path, the number of drawable knots is one more than the number of drawable segments. For a closed path, the number of drawable knots and the number of drawable segments are the same.
      Parameters:
      path - the path
      Returns:
      the number of drawable segments
      Throws:
      IllegalStateException - if the path does not start with a segment whose type is PathIterator.SEG_MOVE.
    • isClosed

      public static boolean isClosed(Path2D path)
      Determine if the first continuous portion of a path is closed. The test ignores any segments
      Parameters:
      path - the path
      Returns:
      true if the path is closed; false otherwise
    • firstTangent

      public static double[] firstTangent(Path2D path) throws IllegalArgumentException
      Get the tangent vector for the start of a path.
      Parameters:
      path - the path
      Returns:
      the tangent vector; null if the path's first component is a closed path
      Throws:
      IllegalArgumentException - if the path did not start with a PathIterator.SEG_MOVETO segment or if the path had only PathIterator.SEG_MOVETO segments before a PathIterator.SEG_CLOSE segment
    • lastTangent

      public static double[] lastTangent(Path2D path)
      Get the tangent vector for the end of a path. The tangent vector, if it exists and has a non-zero length, will have unit length.
      Parameters:
      path - the path
      Returns:
      the tangent vector; null if the last component of the path is a closed path
      Throws:
      IllegalArgumentException - if the path did not start with a PathIterator.SEG_MOVETO segment, if the path ends with a PathIterator.SEG_MOVETO segment, or if the segment type is not recognized
    • firstNormal

      public static double[] firstNormal(Path2D path) throws IllegalArgumentException
      Get the normal vector for the start of a path. The normal vector, if it exists and has a non-zero length, will have unit length. This vector is perpendicular to the tangent vector and is equal to a vector that results from a 90 degree counterclockwise rotation of the tangent vector.
      Parameters:
      path - the path
      Returns:
      the normal vector; null if the path's first component is a closed path
      Throws:
      IllegalArgumentException - if the path did not start with a PathIterator.SEG_MOVETO segment or if the path had only PathIterator.SEG_MOVETO segments before a PathIterator.SEG_CLOSE segment
    • lastNormal

      public static double[] lastNormal(Path2D path)
      Get the normal vector for the end of a path. The normal vector, if it exists and has a non-zero length, will have unit length. This vector is perpendicular to the tangent vector and is equal to a vector that results from a 90 degree counterclockwise rotation of the tangent vector.
      Parameters:
      path - the path
      Returns:
      the normal vector; null if the last component of the path is a closed path
      Throws:
      IllegalArgumentException - if the path did not start with a PathIterator.SEG_MOVETO segment, if the path ends with a PathIterator.SEG_MOVETO segment, or if the segment type is not recognized