svg_path

Core SVG path data structures and constructors.

This module models paths as a list of subpaths, and subpaths as continuous segment lists. Use svg_path/parse and svg_path/serialize when working directly with SVG path data strings.

Coordinates follow SVG’s page convention: positive x points right and positive y points down. Angles are in degrees unless explicitly stated otherwise. Segment parameters normally run from 0.0 to 1.0; evaluation and unchecked segment splitting also allow extrapolation. A parameter is not an arc-length fraction. Use the *_at_length helpers for traveled distances, and *_directions for singularity-safe unit tangents.

Types

An axis-aligned bounding box.

pub type BoundingBox {
  BoundingBox(min: Point, max: Point)
}

Constructors

Options for classifying a point relative to a subpath’s fill area.

pub type ContainmentOptions {
  ContainmentOptions(
    tolerance: Float,
    samples: Int,
    max_iterations: Int,
    fallback_ray_angles: List(Float),
  )
}

Constructors

  • ContainmentOptions(
      tolerance: Float,
      samples: Int,
      max_iterations: Int,
      fallback_ray_angles: List(Float),
    )

    Arguments

    tolerance

    Finite, positive distance at which a point is classified as boundary.

    samples

    Number of scan samples used by projection and crossing queries.

    max_iterations

    Maximum refinement steps for projection and crossing candidates.

    fallback_ray_angles

    Fallback ray angles, in degrees, tried when the heuristic ray gives inconsistent positive/negative containment answers.

Options for detecting scalar zero crossings along a segment.

pub type CrossingOptions {
  CrossingOptions(
    samples: Int,
    signed_line_distance_tolerance: Float,
    max_iterations: Int,
  )
}

Constructors

  • CrossingOptions(
      samples: Int,
      signed_line_distance_tolerance: Float,
      max_iterations: Int,
    )

    Arguments

    samples

    Number of equal parameter windows scanned before refinement.

    signed_line_distance_tolerance

    Maximum finite, positive signed line-distance residual accepted during refinement.

    max_iterations

    Maximum bisection steps for one candidate window.

Constraint state of one fitted cubic control handle.

pub type CubicFitHandleState {
  UnconstrainedHandle
  PositiveHandle
  CollapsedHandle
}

Constructors

  • UnconstrainedHandle

    The fit did not constrain this handle to a direction.

  • PositiveHandle

    The direction-constrained handle has positive length.

  • CollapsedHandle

    The nonnegative fit selected zero handle length.

Error measurements and active handle constraints for a fitted cubic.

pub type CubicFitReport {
  CubicFitReport(
    root_sum_square: Float,
    root_mean_square: Float,
    max: Float,
    start_handle: CubicFitHandleState,
    end_handle: CubicFitHandleState,
  )
}

Constructors

  • CubicFitReport(
      root_sum_square: Float,
      root_mean_square: Float,
      max: Float,
      start_handle: CubicFitHandleState,
      end_handle: CubicFitHandleState,
    )

    Arguments

    root_sum_square

    sqrt(sum(distance(sample, fitted)^2)).

    root_mean_square

    sqrt(sum(distance(sample, fitted)^2) / sample_count).

    max

    The largest sample distance.

    start_handle

    Constraint state of the handle adjacent to the segment start.

    end_handle

    Constraint state of the handle adjacent to the segment end.

Options for singularity-safe direction queries.

pub type DirectionOptions {
  DirectionOptions(relative_tolerance: Float)
}

Constructors

  • DirectionOptions(relative_tolerance: Float)

    Arguments

    relative_tolerance

    Candidate vectors at or below this fraction of the largest local candidate are treated as collapsed. This must be finite and non-negative; zero skips only exact zero vectors.

Singularity-safe unit traversal directions at a path parameter.

incoming points in the direction of traversal as the parameter is approached. outgoing points in the direction of traversal after the parameter. Either side is absent when the addressed geometry has no direction on that side.

pub type Directions {
  Directions(
    incoming: option.Option(Point),
    outgoing: option.Option(Point),
  )
}

Constructors

Options for finding the distance from a point to a segment.

samples controls arc projection and the explicit sampling-based projection API. Quadratic and cubic projection uses polynomial root isolation instead.

pub type DistanceOptions {
  DistanceOptions(
    samples: Int,
    tolerance: Float,
    max_iterations: Int,
  )
}

Constructors

  • DistanceOptions(
      samples: Int,
      tolerance: Float,
      max_iterations: Int,
    )

    Arguments

    samples

    Number of equal parameter windows used by sampling-based projection.

    tolerance

    Maximum finite, positive geometric window diameter during refinement.

    max_iterations

    Maximum refinement steps for one projection candidate.

How construction and editing helpers reconcile segment endpoints.

pub type EndpointPolicy {
  Strict
  Wiggle
  WiggleWith(Float)
  Bridge
  WiggleElseBridge
  WiggleElseBridgeWith(Float)
  Custom(
    fn(Segment, Segment, EndpointPolicyContext) -> List(Segment),
  )
}

Constructors

  • Strict

    Endpoints must already match exactly.

  • Wiggle

    Move nearby endpoints together within the default wiggle tolerance.

    Horizontal and vertical lines stay horizontal and vertical. If adjacent horizontal/horizontal or vertical/vertical lines are misaligned, a bridge is inserted regardless of endpoint distance.

  • WiggleWith(Float)

    Move nearby endpoints together within the supplied tolerance.

    Horizontal and vertical lines stay horizontal and vertical. If adjacent horizontal/horizontal or vertical/vertical lines are misaligned, a bridge is inserted regardless of endpoint distance.

  • Bridge

    Keep endpoints unchanged and insert a straight line if needed.

  • WiggleElseBridge

    Try Wiggle; if that fails, use Bridge.

  • WiggleElseBridgeWith(Float)

    Try wiggle with the supplied tolerance; if that fails, use Bridge.

  • Custom(
      fn(Segment, Segment, EndpointPolicyContext) -> List(Segment),
    )

    Reconcile adjacent segments with a caller-provided function.

    For ordinary adjacent pairs, the returned segments replace the pair. For a closing join from the last segment back to the first segment, they replace only the last segment. An empty list deletes the replaced segment or pair. If the returned list is nonempty, its first segment must start where the previous segment started. The callback’s context identifies the first/last forward pair and the separate closing join. Replacement segments are not visited again; only the final replacement is used as previous for the next input.

The position of an endpoint-policy call in construction.

first marks the first forward pair; last marks a forward pair whose next is the final input segment. Both are true for a two-segment input. They describe input traversal, not the size of the replacement list. The separate closing call has only closing true. A singleton has no forward call, but closing calls the policy with that segment twice. Empty subpaths have no calls. Deletions can leave no preceding segment for a remaining input segment, in which case no pairwise call is made.

pub type EndpointPolicyContext {
  EndpointPolicyContext(first: Bool, last: Bool, closing: Bool)
}

Constructors

  • EndpointPolicyContext(first: Bool, last: Bool, closing: Bool)

Errors returned by path construction and editing helpers.

pub type Error {
  AlreadyClosed
  Discontinuous(
    previous_index: Int,
    next_index: Int,
    expected: Point,
    got: Point,
    distance: Float,
  )
  EmptySubpath
  NotClosed
  EmptyPath
  EmptySubpaths
  DegenerateArc
  CannotMapArcNonlinearly
  DegeneratePointPairSimilarity
  InvalidSplice(start: Int, delete: Int, length: Int)
  InvalidSubpathParameter(
    segment_index: Int,
    t: Float,
    length: Int,
  )
  InvalidPathParameter(subpath_index: Int, length: Int)
  InvalidDirectionRelativeTolerance(relative_tolerance: Float)
  IndeterminateDirection
  InvalidWiggleTolerance(tolerance: Float)
  InvalidSubpathInterval(
    from: SubpathParameter,
    to: SubpathParameter,
  )
  InvalidCrossingSamples(samples: Int)
  InvalidCrossingTolerance(tolerance: Float)
  InvalidCrossingMaxIterations(max_iterations: Int)
  CrossingMaxIterationsReached(estimate: Float, value: Float)
  InvalidMinimizeSamples(samples: Int)
  InvalidMinimizeTolerance(tolerance: Float)
  InvalidMinimizeMaxIterations(max_iterations: Int)
  MinimizeMaxIterationsReached(estimate: Float, value: Float)
  InvalidLengthTolerance(tolerance: Float)
  InvalidLengthMaxDepth(max_depth: Int)
  LengthMaxDepthReached(estimate: Float, error: Float)
  InvalidZeroLengthTolerance(tolerance: Float)
  InvalidLengthDistance(distance: Float, length: Float)
  InvalidSubdivisionMaxLength(max_length: Float)
  InvalidParametricTolerance(tolerance: Float)
  InvalidParametricSamplesPerPiece(samples: Int)
  InvalidParametricInitialPieceCount(piece_count: Int)
  InvalidParametricMaxDepth(max_depth: Int)
  InvalidParametricInterval(start: Float, end: Float)
  NonFiniteParametricPoint(parameter: Float, point: Point)
  NonFiniteParametricTangent(parameter: Float, tangent: Point)
  ParametricMaxDepthReached(error: Float)
  ParametricFitFailed
  DegenerateCubicFitTangent
  UnderdeterminedCubicFit
  InvalidLinearizeTolerance(tolerance: Float)
  InvalidLinearizeMaxDepth(max_depth: Int)
  LinearizeMaxDepthReached(error: Float)
  InvalidDistanceSamples(samples: Int)
  InvalidDistanceTolerance(tolerance: Float)
  InvalidDistanceMaxIterations(max_iterations: Int)
  DistanceMaxIterationsReached(estimate: Float, value: Float)
  DistanceRootIsolationFailed
  InvalidContainmentTolerance(tolerance: Float)
  InvalidContainmentSamples(samples: Int)
  InvalidContainmentMaxIterations(max_iterations: Int)
  InvalidContainmentRayAngle(angle: Float)
  InconsistentContainment
  IndeterminateWindingSideLevels
  InconsistentWindingSideLevels
  InvalidIntersectionTolerance(tolerance: Float)
  InvalidParameterSnapTolerance(tolerance: Float)
  InvalidOverlapTolerance(tolerance: Float)
  InvalidOverlapSamples(samples: Int)
  InvalidIntersectionMaxDepth(max_depth: Int)
  IntersectionTerminalWindowLimitExceeded(limit: Int)
  IntersectionDepthLimitReached(
    left_from: Float,
    left_to: Float,
    right_from: Float,
    right_to: Float,
  )
  InvalidIntersectionParameterSnapExponent(exponent: Int)
  InvalidSelfIntersectionMinimumArcLengthSeparation(
    minimum_arc_length_separation: Float,
  )
  InvalidSelfIntersectionDistanceTolerance(
    distance_tolerance: Float,
  )
  OverlappingSegments
  InternalOverlapClassificationInconsistency
  InternalUncertifiedSegmentIntersection(
    left_distance: Float,
    right_distance: Float,
    tolerance: Float,
  )
  InternalOverlapParameterCorrespondenceInconsistency
  NonAffineOverlapCorrespondence
  MultipleNonemptySubpaths
  NotCloseEnough(expected: Point, got: Point, tolerance: Float)
  SplitOutsideSegment
}

Constructors

  • AlreadyClosed

    The subpath is already closed and cannot accept more segments.

  • Discontinuous(
      previous_index: Int,
      next_index: Int,
      expected: Point,
      got: Point,
      distance: Float,
    )

    A segment starts somewhere other than the previous segment’s end point.

    previous_index is the segment whose end point was expected. next_index is the segment whose start point did not match. distance is the distance between expected and got.

  • EmptySubpath

    The operation requires a non-empty subpath.

  • NotClosed

    The operation requires a closed subpath.

  • EmptyPath

    The operation requires a path with at least one subpath.

  • EmptySubpaths

    The operation requires a path with at least one non-empty subpath.

  • DegenerateArc

    The arc cannot be converted to center-parameter form.

  • CannotMapArcNonlinearly

    Nonlinear point mapping cannot preserve an SVG arc segment.

  • DegeneratePointPairSimilarity

    A point-pair similarity needs distinct source points.

  • InvalidSplice(start: Int, delete: Int, length: Int)

    A splice was requested with invalid bounds.

    This is returned when start is negative, delete is negative, or start is greater than the subpath length.

  • InvalidSubpathParameter(
      segment_index: Int,
      t: Float,
      length: Int,
    )

    A subpath parameter was outside the valid segment index or 0.0..1.0 range.

  • InvalidPathParameter(subpath_index: Int, length: Int)

    A path parameter was outside the valid subpath index range.

  • InvalidDirectionRelativeTolerance(relative_tolerance: Float)

    A direction relative tolerance must be finite and non-negative.

  • IndeterminateDirection

    Geometry has no usable direction for the requested operation.

  • InvalidWiggleTolerance(tolerance: Float)

    A custom endpoint wiggle tolerance must be finite and non-negative.

  • InvalidSubpathInterval(
      from: SubpathParameter,
      to: SubpathParameter,
    )

    A subpath interval would not produce a positive-length piece.

  • InvalidCrossingSamples(samples: Int)

    The number of crossing scan samples must be greater than zero.

  • InvalidCrossingTolerance(tolerance: Float)

    The crossing tolerance must be finite and greater than zero.

  • InvalidCrossingMaxIterations(max_iterations: Int)

    The crossing bisection iteration limit must be greater than zero.

  • CrossingMaxIterationsReached(estimate: Float, value: Float)

    A bracketed crossing could not be refined within the iteration limit.

  • InvalidMinimizeSamples(samples: Int)

    The number of minimization scan samples must be greater than zero.

  • InvalidMinimizeTolerance(tolerance: Float)

    The minimization tolerance must be finite and greater than zero.

  • InvalidMinimizeMaxIterations(max_iterations: Int)

    The minimization iteration limit must be greater than zero.

  • MinimizeMaxIterationsReached(estimate: Float, value: Float)

    A minimization window could not be refined within the iteration limit.

  • InvalidLengthTolerance(tolerance: Float)

    The length approximation tolerance must be finite and greater than zero.

  • InvalidLengthMaxDepth(max_depth: Int)

    The length approximation recursion limit must be greater than zero.

  • LengthMaxDepthReached(estimate: Float, error: Float)

    A length approximation could not be refined within the recursion limit.

  • InvalidZeroLengthTolerance(tolerance: Float)

    The zero-length tolerance must be finite and zero or greater.

  • InvalidLengthDistance(distance: Float, length: Float)

    A requested arc-length distance was outside 0.0..length.

  • InvalidSubdivisionMaxLength(max_length: Float)

    The maximum segment length must be finite and greater than zero.

  • InvalidParametricTolerance(tolerance: Float)

    Parametric fitting tolerance must be finite and greater than zero.

  • InvalidParametricSamplesPerPiece(samples: Int)

    Parametric fitting needs at least two interior samples per piece.

  • InvalidParametricInitialPieceCount(piece_count: Int)

    Parametric fitting initial piece count must be greater than zero.

  • InvalidParametricMaxDepth(max_depth: Int)

    Parametric fitting recursion depth must be zero or greater.

  • InvalidParametricInterval(start: Float, end: Float)

    Parametric fitting needs distinct, finite start and end parameters.

  • NonFiniteParametricPoint(parameter: Float, point: Point)

    The caller-provided parametric function produced a non-finite point.

  • NonFiniteParametricTangent(parameter: Float, tangent: Point)

    The caller-provided tangent function produced a non-finite tangent.

  • ParametricMaxDepthReached(error: Float)

    A parametric interval could not be fitted within the recursion limit. Carries the remaining geometric fitting error, not the recursion depth.

  • ParametricFitFailed

    A parametric interval could not determine a stable cubic fit.

  • DegenerateCubicFitTangent

    A cubic fit tangent was too small to normalize.

  • UnderdeterminedCubicFit

    A cubic fit did not have enough sample information to determine controls.

  • InvalidLinearizeTolerance(tolerance: Float)

    The line approximation tolerance must be finite and greater than zero.

  • InvalidLinearizeMaxDepth(max_depth: Int)

    The line approximation recursion limit must be greater than zero.

  • LinearizeMaxDepthReached(error: Float)

    A segment could not be approximated within the recursion limit. Carries the remaining geometric approximation error, not the recursion depth.

  • InvalidDistanceSamples(samples: Int)

    The number of distance scan samples must be greater than zero.

  • InvalidDistanceTolerance(tolerance: Float)

    The distance tolerance must be finite and greater than zero.

  • InvalidDistanceMaxIterations(max_iterations: Int)

    The distance bisection iteration limit must be greater than zero.

  • DistanceMaxIterationsReached(estimate: Float, value: Float)

    A bracketed distance candidate could not be refined within the iteration limit.

  • DistanceRootIsolationFailed

    Polynomial distance-root isolation produced an inconsistent bracket.

  • InvalidContainmentTolerance(tolerance: Float)

    The containment tolerance must be finite and greater than zero.

  • InvalidContainmentSamples(samples: Int)

    The number of containment samples must be greater than zero.

  • InvalidContainmentMaxIterations(max_iterations: Int)

    The containment iteration limit must be greater than zero.

  • InvalidContainmentRayAngle(angle: Float)

    A containment fallback ray angle must be finite.

  • InconsistentContainment

    Every attempted containment ray gave inconsistent opposite-direction answers.

  • IndeterminateWindingSideLevels

    No regular interior sample could determine a segment’s winding sides.

  • InconsistentWindingSideLevels

    Symmetric regular samples disagreed about a segment’s winding sides.

  • InvalidIntersectionTolerance(tolerance: Float)

    The intersection tolerance must be finite and greater than zero.

  • InvalidParameterSnapTolerance(tolerance: Float)

    The subpath-parameter snap tolerance must be finite and greater than zero.

  • InvalidOverlapTolerance(tolerance: Float)

    The overlap tolerance must be finite and zero or greater.

  • InvalidOverlapSamples(samples: Int)

    Endpoint-projection overlap detection requires at least one sample.

  • InvalidIntersectionMaxDepth(max_depth: Int)

    The intersection subdivision depth must be greater than zero.

  • IntersectionTerminalWindowLimitExceeded(limit: Int)

    Intersection search generated more terminal windows than its safety limit.

  • IntersectionDepthLimitReached(
      left_from: Float,
      left_to: Float,
      right_from: Float,
      right_to: Float,
    )

    Intersection refinement exhausted its depth before resolving this window.

  • InvalidIntersectionParameterSnapExponent(exponent: Int)

    The intersection parameter snap exponent must be between 1 and 15.

  • InvalidSelfIntersectionMinimumArcLengthSeparation(
      minimum_arc_length_separation: Float,
    )

    The self-intersection arc-length separation must be finite and positive.

  • InvalidSelfIntersectionDistanceTolerance(
      distance_tolerance: Float,
    )

    The self-intersection distance tolerance must be finite and positive.

  • OverlappingSegments

    The two segments overlap in more than a single point.

  • InternalOverlapClassificationInconsistency

    Point-intersection logic reported an overlap that the shared overlap classifier did not confirm.

  • InternalUncertifiedSegmentIntersection(
      left_distance: Float,
      right_distance: Float,
      tolerance: Float,
    )

    Point-intersection logic returned parameters that do not evaluate back to the reported point within the requested tolerance.

  • InternalOverlapParameterCorrespondenceInconsistency

    Opposite-direction subpath overlap correspondence checks disagreed.

  • NonAffineOverlapCorrespondence

    Coincident segment portions do not have a single affine correspondence between their parameter intervals.

    Normalize or linearize degenerate, multiply traced, or non-monotone segments before retrying the overlap operation.

  • MultipleNonemptySubpaths

    The path contains more than one non-empty subpath.

  • NotCloseEnough(expected: Point, got: Point, tolerance: Float)

    Two points were too far apart for a wiggle operation to merge them.

  • SplitOutsideSegment

    The requested split point is outside the segment’s 0.0..1.0 parameter range.

The SVG fill rule used for point containment and filled area.

pub type FillRule {
  Nonzero
  EvenOdd
}

Constructors

  • Nonzero
  • EvenOdd

Options for approximating the length of a segment or subpath.

pub type LengthOptions {
  LengthOptions(tolerance: Float, max_depth: Int)
}

Constructors

  • LengthOptions(tolerance: Float, max_depth: Int)

    Arguments

    tolerance

    Maximum finite, positive path-coordinate error in one length estimate.

    max_depth

    Maximum recursive subdivision depth.

Options for approximating segments with straight lines.

pub type LinearizeOptions {
  LinearizeOptions(tolerance: Float, max_depth: Int)
}

Constructors

  • LinearizeOptions(tolerance: Float, max_depth: Int)

    Arguments

    tolerance

    Maximum finite, positive deviation from the line approximation.

    max_depth

    Maximum recursive subdivision depth.

Options for minimizing a scalar function along a segment.

pub type MinimizeOptions {
  MinimizeOptions(
    samples: Int,
    parameter_tolerance: Float,
    max_iterations: Int,
  )
}

Constructors

  • MinimizeOptions(
      samples: Int,
      parameter_tolerance: Float,
      max_iterations: Int,
    )

    Arguments

    samples

    Number of equal parameter windows scanned for local minima.

    parameter_tolerance

    Maximum finite, positive parameter-window width accepted during refinement.

    max_iterations

    Maximum golden-section steps for one candidate window.

Options for building a subpath from a parametric curve.

pub type ParametricOptions {
  ParametricOptions(
    tolerance: Float,
    samples_per_piece: Int,
    initial_piece_count: Int,
    max_depth: Int,
    tangent: option.Option(fn(Float) -> Point),
  )
}

Constructors

  • ParametricOptions(
      tolerance: Float,
      samples_per_piece: Int,
      initial_piece_count: Int,
      max_depth: Int,
      tangent: option.Option(fn(Float) -> Point),
    )

    Arguments

    tolerance

    Maximum finite, positive sampled fitting error for one piece.

    samples_per_piece

    Number of interior fitting samples per candidate piece; at least two.

    initial_piece_count

    Positive number of equal parameter pieces before adaptive subdivision.

    max_depth

    Non-negative maximum recursive subdivision depth; zero forbids refinement.

    tangent

    Optional derivative function used to constrain endpoint tangents.

An SVG path, made of zero or more subpaths.

pub type Path {
  Path(subpaths: List(Subpath))
}

Constructors

A point intersection between two paths.

Multiple parameters are retained on both paths because a single point can be reached through multiple subpaths or through self-intersecting subpaths. Segment-boundary aliases are canonicalized to one traversal address.

pub type PathIntersection {
  PathIntersection(
    point: Point,
    left_parameters: List(PathParameter),
    right_parameters: List(PathParameter),
  )
}

Constructors

A local address on a path.

subpath_index addresses a subpath in the path, and at addresses a segment parameter inside that subpath.

pub type PathParameter {
  PathParameter(subpath_index: Int, at: SubpathParameter)
}

Constructors

A closest-point pair between two paths.

Move-only subpaths are skipped. When multiple pairs are equally nearest, this records one valid pair. The chosen parameters are not guaranteed to be canonical for ties or flat minima.

pub type PathPathProjection {
  PathPathProjection(
    left_at: PathParameter,
    right_at: PathParameter,
    left_point: Point,
    right_point: Point,
    distance: Float,
  )
}

Constructors

The nearest point on a path to an input point.

Move-only subpaths are skipped. When multiple path points are equally nearest, this records one valid nearest point. The chosen point and parameter are not guaranteed to be canonical for ties or flat minima.

pub type PathProjection {
  PathProjection(
    at: PathParameter,
    point: Point,
    distance: Float,
  )
}

Constructors

A point where a path intersects itself.

pub type PathSelfIntersection {
  PathSelfIntersection(
    point: Point,
    parameters: #(PathParameter, PathParameter),
  )
}

Constructors

The signed winding number of a path around a point.

pub type PathWinding {
  Winding(Int)
  BoundaryWinding
}

Constructors

  • Winding(Int)
  • BoundaryWinding

A 2D point.

pub type Point {
  Point(x: Float, y: Float)
}

Constructors

  • Point(x: Float, y: Float)

The position of a point relative to a filled subpath.

pub type PointContainment {
  Inside
  Outside
  Boundary
}

Constructors

  • Inside
  • Outside
  • Boundary

Errors returned by fallible point-mapping helpers.

pub type PointMapError(error) {
  PointMapPathError(error: Error)
  PointMapFunctionError(error: error)
}

Constructors

  • PointMapPathError(error: Error)

    The path structure could not be mapped.

  • PointMapFunctionError(error: error)

    The caller-provided point mapping function failed.

A single SVG path segment.

pub type Segment {
  Line(start: Point, end: Point)
  QuadraticBezier(start: Point, control: Point, end: Point)
  CubicBezier(
    start: Point,
    control1: Point,
    control2: Point,
    end: Point,
  )
  Arc(
    start: Point,
    radius: Point,
    x_axis_rotation: Float,
    large_arc: Bool,
    sweep: Bool,
    end: Point,
  )
}

Constructors

  • Line(start: Point, end: Point)

    A straight line segment.

  • QuadraticBezier(start: Point, control: Point, end: Point)

    A quadratic Bezier curve segment.

  • CubicBezier(
      start: Point,
      control1: Point,
      control2: Point,
      end: Point,
    )

    A cubic Bezier curve segment.

  • Arc(
      start: Point,
      radius: Point,
      x_axis_rotation: Float,
      large_arc: Bool,
      sweep: Bool,
      end: Point,
    )

    An elliptical arc segment. x_axis_rotation is in degrees.

A point intersection between two segments.

pub type SegmentIntersection {
  SegmentIntersection(
    left_t: Float,
    right_t: Float,
    point: Point,
  )
}

Constructors

  • SegmentIntersection(left_t: Float, right_t: Float, point: Point)

A closest-point pair between a segment and a path.

Move-only subpaths are skipped. When multiple pairs are equally nearest, this records one valid pair. The chosen parameters are not guaranteed to be canonical for ties or flat minima.

pub type SegmentPathProjection {
  SegmentPathProjection(
    left_t: Float,
    right_at: PathParameter,
    left_point: Point,
    right_point: Point,
    distance: Float,
  )
}

Constructors

  • SegmentPathProjection(
      left_t: Float,
      right_at: PathParameter,
      left_point: Point,
      right_point: Point,
      distance: Float,
    )

The nearest point on a segment to an input point.

When multiple segment points are equally nearest, this records one valid nearest point. The chosen point and parameter are not guaranteed to be canonical for ties or flat minima.

pub type SegmentProjection {
  SegmentProjection(t: Float, point: Point, distance: Float)
}

Constructors

  • SegmentProjection(t: Float, point: Point, distance: Float)

A closest-point pair between two segments.

When multiple pairs are equally nearest, this records one valid pair. The chosen parameters are not guaranteed to be canonical for ties or flat minima.

pub type SegmentSegmentProjection {
  SegmentSegmentProjection(
    left_t: Float,
    right_t: Float,
    left_point: Point,
    right_point: Point,
    distance: Float,
  )
}

Constructors

  • SegmentSegmentProjection(
      left_t: Float,
      right_t: Float,
      left_point: Point,
      right_point: Point,
      distance: Float,
    )

A closest-point pair between a segment and a subpath.

When multiple pairs are equally nearest, this records one valid pair. The chosen parameters are not guaranteed to be canonical for ties or flat minima.

pub type SegmentSubpathProjection {
  SegmentSubpathProjection(
    left_t: Float,
    right_at: SubpathParameter,
    left_point: Point,
    right_point: Point,
    distance: Float,
  )
}

Constructors

Options for finding self-intersections in one subpath.

pub type SelfIntersectionOptions {
  SelfIntersectionOptions(
    minimum_arc_length_separation: Float,
    distance_tolerance: Float,
  )
}

Constructors

  • SelfIntersectionOptions(
      minimum_arc_length_separation: Float,
      distance_tolerance: Float,
    )

    Arguments

    minimum_arc_length_separation

    Finite, positive arc-length separation between two reported addresses.

    distance_tolerance

    Finite, positive distance between coincident points.

A positioned sequence of path segments, optionally closed.

The first segment, when present, starts at the subpath start point. The last segment of a closed subpath, when present, also ends at the subpath start point. Empty subpaths may be open or closed.

The constructor is opaque so that these invariants are maintained. Use subpath, subpath_empty, subpath_append_segment, or their _with variants to build values.

pub opaque type Subpath

A point intersection between two subpaths.

Multiple parameters are retained on both subpaths because a single point can be reached multiple times by a self-intersecting subpath. Segment-boundary aliases are canonicalized to one traversal address.

pub type SubpathIntersection {
  SubpathIntersection(
    point: Point,
    left_parameters: List(SubpathParameter),
    right_parameters: List(SubpathParameter),
  )
}

Constructors

A local address on a subpath segment.

segment_index addresses a segment in the subpath, and t is that segment’s local parameter. Subpath APIs require t to be inside 0.0..1.0; unlike segment APIs, subpath parameters do not extrapolate.

pub type SubpathParameter {
  SubpathParameter(segment_index: Int, t: Float)
}

Constructors

  • SubpathParameter(segment_index: Int, t: Float)

A closest-point pair between a subpath and a path.

Move-only subpaths are skipped. When multiple pairs are equally nearest, this records one valid pair. The chosen parameters are not guaranteed to be canonical for ties or flat minima.

pub type SubpathPathProjection {
  SubpathPathProjection(
    left_at: SubpathParameter,
    right_at: PathParameter,
    left_point: Point,
    right_point: Point,
    distance: Float,
  )
}

Constructors

The nearest point on a subpath to an input point.

When multiple subpath points are equally nearest, this records one valid nearest point. The chosen point and parameter are not guaranteed to be canonical for ties or flat minima.

pub type SubpathProjection {
  SubpathProjection(
    at: SubpathParameter,
    point: Point,
    distance: Float,
  )
}

Constructors

A point where a subpath intersects itself.

pub type SubpathSelfIntersection {
  SubpathSelfIntersection(
    point: Point,
    parameters: #(SubpathParameter, SubpathParameter),
  )
}

Constructors

A closest-point pair between two subpaths.

When multiple pairs are equally nearest, this records one valid pair. The chosen parameters are not guaranteed to be canonical for ties or flat minima.

pub type SubpathSubpathProjection {
  SubpathSubpathProjection(
    left_at: SubpathParameter,
    right_at: SubpathParameter,
    left_point: Point,
    right_point: Point,
    distance: Float,
  )
}

Constructors

Values

pub fn arc_angle_at(
  segment: Segment,
  t t: Float,
) -> Result(Float, Error)

Return the ellipse angle, in degrees, reached at arc parameter t.

This is a root-module convenience wrapper around ellipse.arc_angle_at. Non-arc segments return DegenerateArc.

pub fn arc_center_data(
  segment: Segment,
) -> Result(ellipse.CenterArcData, Error)

Return an elliptical arc segment as center-parameter arc data.

Returns DegenerateArc for non-arc segments, coincident arc endpoints, or either absolute radius at or below 1e-9. Uses ellipse.endpoint_to_center: negative radii are made positive, and radii too small to span the endpoints are enlarged. This does not replace degenerate arcs with lines.

pub fn arc_derivative(
  segment: Segment,
  at t: Float,
) -> Result(Point, Error)

Return an arc segment’s derivative with respect to parameter t.

This is a root-module convenience wrapper around ellipse.arc_derivative that accepts an svg_path.Arc segment and returns svg_path.Point. Non-arc segments return DegenerateArc.

pub fn arc_derivative_at_angle(
  segment: Segment,
  angle angle: Float,
) -> Result(Point, Error)

Return an arc segment’s derivative at an ellipse angle in degrees.

This is a root-module convenience wrapper around ellipse.arc_derivative_at_angle that accepts an svg_path.Arc segment and returns svg_path.Point. Non-arc segments return DegenerateArc.

pub fn arc_end_angle(segment: Segment) -> Result(Float, Error)

Return the end angle, in degrees, of an arc segment.

This is a root-module convenience wrapper around ellipse.arc_end_angle. Non-arc segments return DegenerateArc.

pub fn arc_from_center_data(
  data: ellipse.CenterArcData,
) -> Segment

Create an elliptical arc segment from center-parameter arc data.

pub fn arc_from_endpoint_data(
  data: ellipse.EndpointArcData,
) -> Segment

Create an elliptical arc segment from endpoint-parameter arc data.

pub fn arc_point(
  segment: Segment,
  at t: Float,
) -> Result(Point, Error)

Evaluate an arc segment at parameter t.

This is a root-module convenience wrapper around ellipse.arc_point that accepts an svg_path.Arc segment and returns svg_path.Point. Non-arc segments return DegenerateArc.

pub fn arc_point_at_angle(
  segment: Segment,
  angle angle: Float,
) -> Result(Point, Error)

Evaluate an arc segment at an ellipse angle in degrees.

This is a root-module convenience wrapper around ellipse.arc_point_at_angle that accepts an svg_path.Arc segment and returns svg_path.Point. Non-arc segments return DegenerateArc.

pub fn bounding_box_center(box: BoundingBox) -> Point

Return the center point of a bounding box.

pub fn bounding_box_height(box: BoundingBox) -> Float

Return the height of a bounding box.

pub fn bounding_box_taxicab_diameter(box: BoundingBox) -> Float

Return the taxicab diameter of a bounding box.

This is the box width plus the box height.

pub fn bounding_box_union(
  first: BoundingBox,
  second: BoundingBox,
) -> BoundingBox

Return the smallest axis-aligned bounding box containing both boxes.

pub fn bounding_box_union_many(
  boxes: List(BoundingBox),
) -> Result(BoundingBox, Nil)

Return the smallest axis-aligned bounding box containing every box.

pub fn bounding_box_width(box: BoundingBox) -> Float

Return the width of a bounding box.

pub fn default_containment_options() -> ContainmentOptions

Return the default options for point containment.

pub fn default_crossing_options() -> CrossingOptions

Return the default options for segment crossing detection.

pub fn default_direction_options() -> DirectionOptions

Return the default options for singularity-safe direction queries.

pub fn default_distance_options() -> DistanceOptions

Return the default options for point-to-segment distance measurement.

pub fn default_length_options() -> LengthOptions

Return the default options for segment and subpath length approximation.

pub fn default_linearize_options() -> LinearizeOptions

Return the default options for straight-line approximation.

pub fn default_minimize_options() -> MinimizeOptions

Return the default options for segment minimization.

pub fn default_parametric_options() -> ParametricOptions

Return the default options for parametric subpath fitting.

pub fn default_self_intersection_options() -> SelfIntersectionOptions

Return the default options for subpath and path self-intersection detection.

pub fn fit_cubic_with_endpoint_tangents(
  start start: Point,
  end end: Point,
  start_tangent start_tangent: Point,
  end_tangent end_tangent: Point,
  samples samples: List(#(Float, Point)),
) -> Result(#(Segment, CubicFitReport), Error)

Fit a cubic Bezier segment with fixed endpoints and endpoint tangents.

This is a root-module convenience wrapper around bezier.fit_cubic_with_endpoint_tangents. It accepts svg_path.Point values, returns an svg_path.CubicBezier segment, and maps fit failures into svg_path.Error.

pub fn fit_cubic_with_endpoints(
  start start: Point,
  end end: Point,
  samples samples: List(#(Float, Point)),
) -> Result(#(Segment, CubicFitReport), Error)

Fit a cubic Bezier segment with fixed endpoints and no tangent constraints.

This is a root-module convenience wrapper around bezier.fit_cubic_with_endpoints. It accepts svg_path.Point values, returns an svg_path.CubicBezier segment, and maps fit failures into svg_path.Error.

pub fn path_append_subpath(path: Path, subpath: Subpath) -> Path

Append a subpath to the end of a path.

pub fn path_arcs_to_cubic_beziers(path: Path) -> Path

Convert every arc in a path to cubic Bezier curves.

This applies subpath_arcs_to_cubic_beziers to each subpath.

pub fn path_as_subpath(path: Path) -> Result(Subpath, Error)

Convert a path with zero or one non-empty subpaths into a subpath.

Empty subpaths are ignored. If more than one non-empty subpath is present, this returns MultipleNonemptySubpaths. If a path has only empty subpaths, the first empty subpath is returned.

pub fn path_bounding_box(
  path: Path,
) -> Result(BoundingBox, Error)

Return the exact axis-aligned bounding box of all non-empty subpaths.

pub fn path_by_point_pair_similarity(
  path: Path,
  source_start source_start: Point,
  source_end source_end: Point,
  target_start target_start: Point,
  target_end target_end: Point,
) -> Result(Path, Error)

Map a path by the similarity taking source_start and source_end to target_start and target_end.

pub fn path_combine(paths: List(Path)) -> Path

Combine paths by concatenating their subpaths.

pub fn path_containment(
  point: Point,
  within path: Path,
  using fill_rule: FillRule,
) -> Result(PointContainment, Error)

Classify a point relative to a path’s combined fill area.

Winding and crossing counts are accumulated across all non-move-only subpaths. Each open subpath is implicitly closed independently. A boundary match on any subpath takes precedence. Empty and move-only paths are Outside.

pub fn path_containment_with(
  point: Point,
  within path: Path,
  using fill_rule: FillRule,
  options options: ContainmentOptions,
) -> Result(PointContainment, Error)

Classify a point relative to a path’s combined fill area using explicit options.

pub fn path_derivative(
  path: Path,
  at parameter: PathParameter,
) -> Result(Point, Error)

Return a path’s subpath derivative at a path parameter.

pub fn path_derivative_at_length(
  path: Path,
  distance distance: Float,
) -> Result(Point, Error)

Return the path derivative at a traveled distance from the path start.

pub fn path_derivative_at_length_with(
  path: Path,
  distance distance: Float,
  options options: LengthOptions,
) -> Result(Point, Error)

Return the path derivative at a traveled distance using explicit options.

pub fn path_directions(
  path: Path,
  at parameter: PathParameter,
) -> Result(Directions, Error)

Return singularity-safe unit traversal directions at a path parameter.

pub fn path_directions_with(
  path: Path,
  at parameter: PathParameter,
  options options: DirectionOptions,
) -> Result(Directions, Error)

Return singularity-safe unit traversal directions using explicit options.

pub fn path_distance(
  point: Point,
  to path: Path,
) -> Result(Float, Error)

Return the shortest distance from a point to a path.

Move-only subpaths are skipped.

pub fn path_distance_with(
  point: Point,
  to path: Path,
  options options: DistanceOptions,
) -> Result(Float, Error)

Return the shortest distance from a point to a path using explicit options.

pub fn path_empty() -> Path

Create an empty path.

pub fn path_end(path: Path) -> Result(Point, Error)

Return the end point of the last subpath in a path.

pub fn path_filter_subpaths(
  path: Path,
  keeping predicate: fn(Subpath) -> Bool,
) -> Path

Keep only the subpaths that satisfy a predicate.

pub fn path_length(path: Path) -> Result(Float, Error)

Return the approximate length of a path.

Empty paths have length 0.0. Move-only subpaths contribute 0.0.

pub fn path_length_upper_bound(
  path: Path,
) -> Result(Float, Error)

Sum the cheap segment-length upper bounds across a path’s subpaths.

Empty paths and move-only subpaths contribute 0.0; gaps between subpaths contribute nothing. See segment_length_upper_bound for numerical limits.

pub fn path_length_with(
  path: Path,
  options options: LengthOptions,
) -> Result(Float, Error)

Return the approximate length of a path using explicit options.

pub fn path_map_points(
  path: Path,
  with f: fn(Point) -> Point,
) -> Result(Path, Error)

Map the defining points of every segment in a path.

Each subpath’s closed state is preserved. For nonlinear functions, this maps endpoints and control points, not the exact image of every point on each rendered curve. If any segment is an arc, this returns CannotMapArcNonlinearly.

pub fn path_map_subpaths(
  path: Path,
  with f: fn(Subpath) -> Subpath,
) -> Path

Map over the subpaths in a path.

pub fn path_parameter_at_length(
  path: Path,
  distance distance: Float,
) -> Result(PathParameter, Error)

Return the path parameter at a traveled distance from the path start.

The distance is measured across subpaths in path order. Move-only subpaths contribute no length and are skipped for lookup. The returned value is an ordinary public PathParameter.

pub fn path_parameter_at_length_with(
  path: Path,
  distance distance: Float,
  options options: LengthOptions,
) -> Result(PathParameter, Error)

Return the path parameter at a traveled distance using explicit options.

pub fn path_parameter_compare(
  a: PathParameter,
  b: PathParameter,
) -> order.Order

Compare two path parameters by subpath index, then subpath parameter.

pub fn path_point(
  path: Path,
  at parameter: PathParameter,
) -> Result(Point, Error)

Evaluate a path at a path parameter.

pub fn path_point_at_length(
  path: Path,
  distance distance: Float,
) -> Result(Point, Error)

Return the path point at a traveled distance from the path start.

pub fn path_point_at_length_with(
  path: Path,
  distance distance: Float,
  options options: LengthOptions,
) -> Result(Point, Error)

Return the path point at a traveled distance using explicit options.

pub fn path_projection(
  point: Point,
  to path: Path,
) -> Result(PathProjection, Error)

Return the nearest point on a path to an input point.

Move-only subpaths are skipped. An empty path returns EmptyPath; a path containing only move-only subpaths returns EmptySubpaths.

pub fn path_projection_with(
  point: Point,
  to path: Path,
  options options: DistanceOptions,
) -> Result(PathProjection, Error)

Return the nearest point on a path to an input point using explicit options.

pub fn path_rebuild_with(
  path: Path,
  policy endpoint_policy: EndpointPolicy,
) -> Result(Path, Error)

Rebuild every subpath in a path using an endpoint policy.

This re-runs endpoint reconciliation on each subpath’s current segment list and preserves each subpath’s open/closed state. Empty subpaths are preserved unchanged.

pub fn path_reverse(path: Path) -> Path

Reverse the traversal direction of a path.

This reverses each subpath and reverses the path’s subpath order.

pub fn path_second_derivative(
  path: Path,
  at parameter: PathParameter,
) -> Result(Point, Error)

Return a path’s segment second derivative at a path parameter.

pub fn path_start(path: Path) -> Result(Point, Error)

Return the start point of the first subpath in a path.

pub fn path_subdivide_to_max_length(
  path: Path,
  max_length max_length: Float,
) -> Result(Path, Error)

Subdivide every segment in a path into pieces of at most max_length.

Existing subpath boundaries and closed states are preserved.

pub fn path_subdivide_to_max_length_with(
  path: Path,
  max_length max_length: Float,
  options options: LengthOptions,
) -> Result(Path, Error)

Subdivide every segment in a path into pieces of at most max_length using explicit length options.

pub fn path_subpaths(path: Path) -> List(Subpath)

Return the subpaths in a path.

pub fn path_to_cubic_beziers(path: Path) -> Path

Convert every segment in a path to cubic Bezier curves.

This applies subpath_to_cubic_beziers to each subpath.

pub fn path_to_lines(path: Path) -> Result(Path, Error)

Approximate every segment in a path with straight lines.

Subpath order, move-only subpaths, and closed states are preserved.

pub fn path_to_lines_with(
  path: Path,
  options options: LinearizeOptions,
) -> Result(Path, Error)

Approximate every segment in a path with straight lines using explicit options.

pub fn path_try_map_points(
  path: Path,
  with f: fn(Point) -> Result(Point, error),
) -> Result(Path, PointMapError(error))

Map the defining points of every segment in a path with a fallible function.

This has the same geometry semantics as path_map_points, but the mapping function may reject individual points.

pub fn path_winding(
  point: Point,
  within path: Path,
) -> Result(PathWinding, Error)

Return the signed winding number of a path around a point.

Open subpaths are implicitly closed, matching path_containment. If the point is within the boundary tolerance of any non-empty subpath, the result is BoundaryWinding because the winding number is not numerically stable at that point. A visually clockwise loop contributes +1; a counterclockwise loop contributes -1.

pub fn path_winding_with(
  point: Point,
  within path: Path,
  options options: ContainmentOptions,
) -> Result(PathWinding, Error)

Return the signed winding number of a path around a point using explicit containment options.

pub fn point_by_point_pair_similarity(
  point: Point,
  source_start source_start: Point,
  source_end source_end: Point,
  target_start target_start: Point,
  target_end target_end: Point,
) -> Result(Point, Error)

Map a point by the similarity taking source_start and source_end to target_start and target_end.

If the input point is exactly source_start or source_end, the returned point is exactly the corresponding target point.

pub fn points_bounding_box(
  points: List(Point),
) -> Result(BoundingBox, Nil)

Return the smallest axis-aligned bounding box containing every point.

pub fn segment_arcs_to_cubic_beziers(
  segment: Segment,
) -> List(Segment)

Convert an arc segment to cubic Bezier curves, preserving other segments.

Non-arc segments are returned unchanged as a single-item list. An arc may become several cubic Bezier segments.

pub fn segment_as_path(segment: Segment) -> Path

View a segment as a path containing one one-segment open subpath.

pub fn segment_as_subpath(segment: Segment) -> Subpath

View a segment as a one-segment open subpath.

This conversion is total because a single segment is necessarily a continuous segment sequence.

pub fn segment_between(
  segment: Segment,
  from from: Float,
  to to: Float,
) -> Result(Segment, Error)

Return the portion of a segment between two parameters.

from and to are not clamped. Values outside 0.0..1.0 extrapolate along the same segment. If from is greater than to, the returned segment traverses the interval in reverse.

pub fn segment_between_inside(
  segment: Segment,
  from from: Float,
  to to: Float,
) -> Result(Segment, Error)

Return the portion of a segment between two parameters.

from and to must be inside 0.0..1.0, inclusive. If from is greater than to, the returned segment traverses the interval in reverse.

pub fn segment_between_lengths(
  segment: Segment,
  from from: Float,
  to to: Float,
) -> Result(Segment, Error)

Return the portion of a segment between two traveled distances.

Distances are measured in path coordinate units from the segment start and must be inside 0.0..length, inclusive. If from is greater than to, the returned segment traverses the interval in reverse.

pub fn segment_between_lengths_many(
  segment: Segment,
  between distances: List(Float),
) -> Result(List(Segment), Error)

Return segment portions between adjacent traveled distances.

Distances are measured in path coordinate units from the segment start and must be inside 0.0..length, inclusive. Empty and singleton lists return an empty list.

pub fn segment_between_lengths_many_with(
  segment: Segment,
  between distances: List(Float),
  options options: LengthOptions,
) -> Result(List(Segment), Error)

Return segment portions between adjacent traveled distances using explicit length options.

pub fn segment_between_lengths_with(
  segment: Segment,
  from from: Float,
  to to: Float,
  options options: LengthOptions,
) -> Result(Segment, Error)

Return the portion of a segment between two traveled distances using explicit length options.

pub fn segment_between_many(
  segment: Segment,
  between points: List(Float),
) -> Result(List(Segment), Error)

Return segment portions between adjacent parameters.

Parameters are not clamped. Values outside 0.0..1.0 extrapolate along the same segment. Empty and singleton lists return an empty list.

pub fn segment_between_many_inside(
  segment: Segment,
  between points: List(Float),
) -> Result(List(Segment), Error)

Return segment portions between adjacent parameters.

All parameters must be inside 0.0..1.0, inclusive. Empty and singleton lists return an empty list.

pub fn segment_bounding_box(
  segment: Segment,
) -> Result(BoundingBox, Error)

Return a segment’s exact axis-aligned bounding box.

pub fn segment_bounding_polygon(
  segment: Segment,
) -> Result(List(Point), Error)

Return a convex polygon enclosing the segment, in visual clockwise order.

The first vertex is the segment start when it is a hull vertex; otherwise it is the lexicographically smallest vertex (x, then y). The first vertex is not repeated at the end. Point and line degeneracies return one or two vertices. Beziers use their control-point hull; arcs use tangent triangles spanning at most 90 degrees on the corrected ellipse, then their hull. This is an ordinary floating-point bound, not outward-rounded arithmetic. Arcs rejected by arc_center_data return DegenerateArc; see that function for endpoint and radius restrictions.

pub fn segment_bounding_polygon_between(
  segment: Segment,
  from from: Float,
  to to: Float,
) -> Result(List(Point), Error)

Enclose the segment portion between from and to, both in 0.0..1.0.

Reversed intervals are allowed. The boundary remains visually clockwise; its preferred first vertex is the point at from, when that is a hull vertex. Equal parameters return one point. Other conventions are those of segment_bounding_polygon. Out-of-range parameters return SplitOutsideSegment.

pub fn segment_by_point_pair_similarity(
  segment: Segment,
  source_start source_start: Point,
  source_end source_end: Point,
  target_start target_start: Point,
  target_end target_end: Point,
) -> Result(Segment, Error)

Map a segment by the similarity taking source_start and source_end to target_start and target_end.

Segment defining points exactly equal to source_start or source_end are mapped exactly to the corresponding target point.

pub fn segment_chord_length(segment: Segment) -> Float

Return the distance between a segment’s start and end points.

This is the endpoint chord length. It can be zero even when a curve has nonzero interior geometry.

pub fn segment_chord_length_squared(segment: Segment) -> Float

Return the squared distance between a segment’s start and end points.

This is the square of the endpoint chord length. It can be zero even when a curve has nonzero interior geometry.

pub fn segment_crossings(
  segment: Segment,
  where f: fn(Point) -> Float,
) -> Result(List(Float), Error)

Find scalar sign-change crossings along a segment using default options.

This samples t in 0.0..1.0, detects sign changes of f(segment_point(t)), and refines each bracket with bisection. It finds crossings visible at the configured sampling resolution; tangent roots and pairs of crossings inside one sample window may be missed.

pub fn segment_crossings_with(
  segment: Segment,
  where f: fn(Point) -> Float,
  options options: CrossingOptions,
) -> Result(List(Float), Error)

Find scalar sign-change crossings along a segment using explicit options.

Once a sign-changing sample window is found, refinement succeeds only when abs(f(segment_point(t))) <= options.signed_line_distance_tolerance.

pub fn segment_derivative(
  segment: Segment,
  at t: Float,
) -> Result(Point, Error)

Return a segment’s derivative with respect to parameter t.

t is not clamped.

pub fn segment_derivative_at_length(
  segment: Segment,
  distance distance: Float,
) -> Result(Point, Error)

Return the segment derivative at a traveled distance from the segment start.

pub fn segment_derivative_at_length_with(
  segment: Segment,
  distance distance: Float,
  options options: LengthOptions,
) -> Result(Point, Error)

Return the segment derivative at a traveled distance using explicit options.

pub fn segment_directions(
  segment: Segment,
  at t: Float,
) -> Result(Directions, Error)

Return singularity-safe unit traversal directions at a segment parameter.

The segment parameter may extrapolate as with segment_point. At 0.0 only outgoing is present, and at 1.0 only incoming is present.

pub fn segment_directions_with(
  segment: Segment,
  at t: Float,
  options options: DirectionOptions,
) -> Result(Directions, Error)

Return singularity-safe unit traversal directions using explicit options.

A zero relative tolerance skips only exactly collapsed candidate vectors.

pub fn segment_distance(
  point: Point,
  to segment: Segment,
) -> Result(Float, Error)

Return the shortest distance from a point to a segment.

Lines are measured exactly. Quadratic Beziers, cubic Beziers, and arcs are measured by finding stationary points of squared distance in 0.0..1.0.

pub fn segment_distance_with(
  point: Point,
  to segment: Segment,
  options options: DistanceOptions,
) -> Result(Float, Error)

Return the shortest distance from a point to a segment using explicit options.

pub fn segment_end(segment: Segment) -> Point

Return the end point of a segment.

pub fn segment_is_zero_length(
  segment: Segment,
  tolerance tolerance: Float,
) -> Result(Bool, Error)

Return whether a segment has length at most tolerance.

tolerance is measured in path coordinate units and may be exactly 0.0 for an exact zero-length check. Lines are measured exactly. Quadratic Beziers, cubic Beziers, and arcs are measured with default length options.

pub fn segment_length(segment: Segment) -> Result(Float, Error)

Return the approximate length of a segment.

Lines are measured exactly. Quadratic Beziers, cubic Beziers, and arcs are approximated by adaptive Simpson integration of segment speed.

pub fn segment_length_upper_bound(
  segment: Segment,
) -> Result(Float, Error)

Return a cheap upper bound on a segment’s length.

Lines use their chord length. Beziers use the sum of their control-polygon edge lengths. Arcs use absolute angular travel in radians times the larger corrected ellipse radius. No numerical integration or subdivision is used. These mathematical upper bounds are evaluated with ordinary floating-point arithmetic, not outward-rounded interval arithmetic, and can substantially overestimate length. Arcs rejected by arc_center_data return DegenerateArc; see that function for endpoint and radius restrictions.

pub fn segment_length_with(
  segment: Segment,
  options options: LengthOptions,
) -> Result(Float, Error)

Return the approximate length of a segment using explicit options.

pub fn segment_map_points(
  segment: Segment,
  with f: fn(Point) -> Point,
) -> Result(Segment, Error)

Map the defining points of a segment.

Lines, quadratic Beziers, and cubic Beziers are mapped by applying f to their endpoints and control points. For nonlinear functions, this is not the exact image of every point on the rendered curve. Arc segments return CannotMapArcNonlinearly because an arbitrary nonlinear mapping does not generally preserve SVG arc parameters.

pub fn segment_minimize(
  segment: Segment,
  measure f: fn(Point) -> Float,
) -> Result(Float, Error)

Return the segment parameter where a scalar function is minimized.

This numerically minimizes f(segment_point(t)) for t in 0.0..1.0.

pub fn segment_minimize_with(
  segment: Segment,
  measure f: fn(Point) -> Float,
  options options: MinimizeOptions,
) -> Result(Float, Error)

Return the segment parameter where a scalar function is minimized using explicit options.

pub fn segment_parameter_at_length(
  segment: Segment,
  distance distance: Float,
) -> Result(Float, Error)

Return the segment parameter at a traveled distance from the segment start.

The distance is measured in path coordinate units, not normalized. Lines are inverted exactly. Quadratic Beziers, cubic Beziers, and arcs are inverted numerically using the same length options as segment_length_with.

pub fn segment_parameter_at_length_with(
  segment: Segment,
  distance distance: Float,
  options options: LengthOptions,
) -> Result(Float, Error)

Return the segment parameter at a traveled distance using explicit options.

pub fn segment_point(
  segment: Segment,
  at t: Float,
) -> Result(Point, Error)

Evaluate a segment at parameter t.

t is not clamped. Values outside 0.0..1.0 extrapolate along the same segment.

pub fn segment_point_at_length(
  segment: Segment,
  distance distance: Float,
) -> Result(Point, Error)

Return the segment point at a traveled distance from the segment start.

pub fn segment_point_at_length_with(
  segment: Segment,
  distance distance: Float,
  options options: LengthOptions,
) -> Result(Point, Error)

Return the segment point at a traveled distance using explicit options.

pub fn segment_projection(
  point: Point,
  to segment: Segment,
) -> Result(SegmentProjection, Error)

Return the nearest point on a segment to an input point.

pub fn segment_projection_with(
  point: Point,
  to segment: Segment,
  options options: DistanceOptions,
) -> Result(SegmentProjection, Error)

Return the nearest point on a segment to an input point using explicit options.

pub fn segment_ray_crossings(
  segment: Segment,
  origin origin: Point,
  direction direction: Point,
) -> Result(List(#(Float, Float)), Error)

Find crossings with a ray’s supporting line using default crossing options.

Like segment_ray_crossings_with, this includes negative ray parameters; callers can filter those out when they need only the positive ray.

pub fn segment_ray_crossings_with(
  segment: Segment,
  origin origin: Point,
  direction direction: Point,
  options options: CrossingOptions,
) -> Result(List(#(Float, Float)), Error)

Find crossings between a segment and a ray’s supporting line.

The ray is represented by an origin and a direction vector. Returned values are #(segment_t, ray_t) pairs where:

segment_point(segment, at: segment_t)
// is approximately
origin + ray_t * direction

ray_t >= 0.0 means the crossing lies on the positive ray. Negative ray_t values are returned too, so callers can choose their own filtering policy.

Unlike segment_crossings_with, this splits the segment at projection extrema before refinement, so tangent line contacts are visible without a fixed sampling grid.

pub fn segment_remap_endpoints(
  segment: Segment,
  new_start new_start: Point,
  new_end new_end: Point,
) -> Result(Segment, Error)

Remap a segment so its current endpoints become new_start and new_end.

The returned segment starts exactly at new_start and ends exactly at new_end.

pub fn segment_reverse(segment: Segment) -> Segment

Reverse the traversal direction of a segment.

pub fn segment_second_derivative(
  segment: Segment,
  at t: Float,
) -> Result(Point, Error)

Return a segment’s second derivative with respect to parameter t.

t is not clamped.

pub fn segment_split(
  segment: Segment,
  at t: Float,
) -> Result(#(Segment, Segment), Error)

Split a segment at parameter t.

t is not clamped. Values outside 0.0..1.0 extrapolate along the same segment.

pub fn segment_split_inside(
  segment: Segment,
  at t: Float,
) -> Result(#(Segment, Segment), Error)

Split a segment at parameter t, returning an error outside 0.0..1.0.

Values exactly at 0.0 or 1.0 are accepted and produce one zero-length segment. For an Arc, the empty portion is a Line and the other portion is the original Arc, since coincident-endpoint arcs have no defined ellipse.

pub fn segment_start(segment: Segment) -> Point

Return the start point of a segment.

pub fn segment_subdivide_to_max_length(
  segment: Segment,
  max_length max_length: Float,
) -> Result(List(Segment), Error)

Subdivide a segment into pieces of at most max_length.

Splits are chosen by traveled arc length, not by equal Bezier or arc parameter spacing. Zero-length segments are returned unchanged.

pub fn segment_subdivide_to_max_length_with(
  segment: Segment,
  max_length max_length: Float,
  options options: LengthOptions,
) -> Result(List(Segment), Error)

Subdivide a segment into pieces of at most max_length using explicit length options.

pub fn segment_to_cubic_beziers(
  segment: Segment,
) -> List(Segment)

Convert a segment to one or more cubic Bezier curves.

Lines and quadratic Beziers are converted exactly. Cubic Beziers are returned unchanged. Arcs may become several cubic Bezier segments.

pub fn segment_to_lines(
  segment: Segment,
) -> Result(List(Segment), Error)

Approximate a segment with one or more straight lines.

Lines are returned unchanged. Beziers and arcs are subdivided until each resulting chord is within the default geometric tolerance. Degenerate arcs fall back to a straight line between their endpoints.

pub fn segment_to_lines_with(
  segment: Segment,
  options options: LinearizeOptions,
) -> Result(List(Segment), Error)

Approximate a segment with straight lines using explicit options.

pub fn segment_try_map_points(
  segment: Segment,
  with f: fn(Point) -> Result(Point, error),
) -> Result(Segment, PointMapError(error))

Map the defining points of a segment with a fallible function.

This has the same geometry semantics as segment_map_points, but the mapping function may reject individual points.

pub fn subpath(segments: List(Segment)) -> Result(Subpath, Error)

Create an open subpath from a non-empty continuous list of segments.

Returns EmptySubpath if the segment list is empty. Use subpath_empty when you need to represent a move-only subpath.

Returns Discontinuous if any segment starts somewhere other than the previous segment’s end point. The error includes the two segment indices that failed to meet.

pub fn subpath_append_segment(
  subpath: Subpath,
  segment: Segment,
) -> Result(Subpath, Error)

Append a segment to an open subpath.

The new segment must start exactly at the current end point.

pub fn subpath_append_segment_with(
  subpath: Subpath,
  segment: Segment,
  policy endpoint_policy: EndpointPolicy,
) -> Result(Subpath, Error)

Append a segment to an open subpath using the given endpoint policy.

Returns AlreadyClosed for a closed source. Otherwise follows subpath_append_segment, allowing the policy to reconcile endpoint gaps. Reconciliation errors propagate; the original subpath start is preserved.

pub fn subpath_arcs_to_cubic_beziers(subpath: Subpath) -> Subpath

Convert every arc in a subpath to cubic Bezier curves.

Lines, quadratic Beziers, and cubic Beziers are preserved. Elliptical arcs are approximated with one or more cubic Beziers, split into chunks of at most a quarter turn. Degenerate arcs fall back to a straight-line cubic Bezier between their endpoints.

pub fn subpath_as_path(subpath: Subpath) -> Path

View a subpath as a path containing that single subpath.

pub fn subpath_assert(segments: List(Segment)) -> Subpath

Create an open subpath from a non-empty continuous list of segments.

Panics if the list is empty or any consecutive endpoints differ exactly.

This is useful for hand-authored paths where invalid continuity would be a programmer error. Use subpath when you want to handle construction errors.

pub fn subpath_assert_append_segment(
  subpath: Subpath,
  segment: Segment,
) -> Subpath

Append a segment, asserting subpath_append_segment.

Panics if the source is closed or the new segment’s start differs from the current end. Use subpath_append_segment for a non-panicking result.

pub fn subpath_assert_append_segment_with(
  subpath: Subpath,
  segment: Segment,
  policy endpoint_policy: EndpointPolicy,
) -> Subpath

Append a segment with an endpoint policy.

Panics if the source is closed or endpoint reconciliation returns an error. See subpath_append_segment_with for the non-panicking version.

pub fn subpath_assert_close(subpath: Subpath) -> Subpath

Close a subpath, asserting subpath_close.

Panics if a nonempty subpath’s end differs from its start. Empty subpaths may be closed.

pub fn subpath_assert_close_with(
  subpath: Subpath,
  policy endpoint_policy: EndpointPolicy,
) -> Subpath

Close a subpath with an endpoint policy, asserting subpath_close_with.

Panics if closing-boundary reconciliation returns an error, including a custom-policy contract violation. Empty subpaths may be closed without invoking the policy. See subpath_close_with for the non-panicking version and policy invocation rules.

pub fn subpath_assert_join(subpaths: List(Subpath)) -> Subpath

Join open subpaths, asserting subpath_join.

Panics for an empty input list, a closed input subpath, or endpoint gaps that prevent continuous reconstruction. Use subpath_join to handle errors.

pub fn subpath_assert_join_with(
  subpaths: List(Subpath),
  policy endpoint_policy: EndpointPolicy,
) -> Subpath

Join open subpaths with an endpoint policy.

Panics for an empty input list, a closed input subpath, or an error during endpoint reconciliation. See subpath_join_with for a non-panicking result.

pub fn subpath_assert_polygon(points: List(Point)) -> Subpath

Create a closed polygon subpath from at least two points.

Panics if fewer than two points are supplied. Points need not be distinct, and the polygon need not be simple or have nonzero area. See subpath_polygon for closing-edge behavior and a non-panicking result.

pub fn subpath_assert_polyline(points: List(Point)) -> Subpath

Create an open polyline subpath from at least two points.

Panics if fewer than two points are supplied. Points need not be distinct. This is the asserting counterpart of subpath_polyline, not a coordinate validation function.

pub fn subpath_assert_splice(
  subpath: Subpath,
  start start: Int,
  delete delete: Int,
  insert insert: List(Segment),
) -> Subpath

Replace a range of segments, asserting the rules of subpath_splice.

Panics for a negative start or delete, a start beyond the segment count, or a result with discontinuous endpoints (including closure). Use subpath_splice for a non-panicking result.

pub fn subpath_assert_splice_with(
  subpath: Subpath,
  start start: Int,
  delete delete: Int,
  insert insert: List(Segment),
  policy endpoint_policy: EndpointPolicy,
) -> Subpath

Replace a range of segments with an endpoint policy.

Panics on any error from subpath_splice_with: invalid index/count as described by subpath_splice, or failure to reconcile the resulting boundaries while preserving the subpath’s closed state.

pub fn subpath_assert_with(
  segments: List(Segment),
  policy endpoint_policy: EndpointPolicy,
) -> Subpath

Create an open subpath with an endpoint policy.

Panics on any error from subpath_with: an empty input list, an endpoint gap the policy cannot reconcile, or a custom replacement that violates the EndpointPolicy contract. Use subpath_with to handle those errors.

pub fn subpath_between(
  subpath: Subpath,
  from from: SubpathParameter,
  to to: SubpathParameter,
) -> Result(Subpath, Error)

Return the open subpath between two subpath parameters.

Parameters must be valid for the subpath and must describe a positive-length interval. Open subpaths reject reversed intervals. Closed subpaths allow wrapped intervals, but equal parameters are still rejected.

pub fn subpath_between_lengths(
  subpath: Subpath,
  from from: Float,
  to to: Float,
) -> Result(Subpath, Error)

Return the open subpath between two traveled distances.

Distances are measured in path coordinate units from the subpath start and must be inside 0.0..length, inclusive. The resulting parameters follow the same interval rules as subpath_between.

pub fn subpath_between_lengths_many(
  subpath: Subpath,
  between distances: List(Float),
) -> Result(List(Subpath), Error)

Split a subpath at multiple traveled distances.

Distances are measured in path coordinate units from the subpath start and must be inside 0.0..length, inclusive. The resulting parameters follow the same split-point rules as subpath_between_many.

pub fn subpath_between_lengths_many_with(
  subpath: Subpath,
  between distances: List(Float),
  options options: LengthOptions,
) -> Result(List(Subpath), Error)

Split a subpath at multiple traveled distances using explicit length options.

pub fn subpath_between_lengths_with(
  subpath: Subpath,
  from from: Float,
  to to: Float,
  options options: LengthOptions,
) -> Result(Subpath, Error)

Return the open subpath between two traveled distances using explicit length options.

pub fn subpath_between_many(
  subpath: Subpath,
  between points: List(SubpathParameter),
) -> Result(List(Subpath), Error)

Split a subpath at multiple subpath parameters.

Open subpaths return the outer pieces as well as the pieces between split points, so an empty split list returns the original subpath. Open split points must be strictly increasing and cannot include the very start or very end. Closed split points must be cyclically increasing and distinct. For closed subpaths, an empty split list returns an empty list, and a single split point returns one open subpath traversing the whole loop from that point back to itself.

pub fn subpath_bounding_box(
  subpath: Subpath,
) -> Result(BoundingBox, Error)

Return a non-empty subpath’s exact axis-aligned bounding box.

pub fn subpath_by_point_pair_similarity(
  subpath: Subpath,
  source_start source_start: Point,
  source_end source_end: Point,
  target_start target_start: Point,
  target_end target_end: Point,
) -> Result(Subpath, Error)

Map a subpath by the similarity taking source_start and source_end to target_start and target_end.

pub fn subpath_close(subpath: Subpath) -> Result(Subpath, Error)

Close a subpath without changing its geometry.

A nonempty subpath’s end must exactly equal its start; otherwise returns Discontinuous. Empty subpaths may be closed. Use subpath_close_with to reconcile endpoints instead of requiring an exact match.

pub fn subpath_close_with(
  subpath: Subpath,
  policy endpoint_policy: EndpointPolicy,
) -> Result(Subpath, Error)

Close a subpath using an endpoint reconciliation policy.

Reconciles a nonempty subpath’s end with its start, even if it is already closed. This invokes the policy exactly once, for the closing pair only; interior pairs are not revisited. Repeated calls can change geometry if the policy is not idempotent. Empty subpaths may be closed and do not invoke the policy.

pub fn subpath_containment(
  point: Point,
  within subpath: Subpath,
  using fill_rule: FillRule,
) -> Result(PointContainment, Error)

Classify a point relative to a subpath’s fill area.

Open and closed subpaths use the same fill geometry: an open subpath is implicitly closed by a straight line from its end to its start. Move-only subpaths have no fill area or boundary.

pub fn subpath_containment_with(
  point: Point,
  within subpath: Subpath,
  using fill_rule: FillRule,
  options options: ContainmentOptions,
) -> Result(PointContainment, Error)

Classify a point relative to a subpath’s fill area using explicit options.

tolerance is measured in path coordinate units and determines the width classified as Boundary. samples and max_iterations control numerical projection and ray-crossing queries.

pub fn subpath_derivative(
  subpath: Subpath,
  at parameter: SubpathParameter,
) -> Result(Point, Error)

Return a subpath’s segment derivative at a subpath parameter.

The parameter must address a segment in the subpath, with t inside 0.0..1.0. Internal segment-end parameters are evaluated through their canonical next-segment start address.

pub fn subpath_derivative_at_length(
  subpath: Subpath,
  distance distance: Float,
) -> Result(Point, Error)

Return the subpath derivative at a traveled distance from the subpath start.

pub fn subpath_derivative_at_length_with(
  subpath: Subpath,
  distance distance: Float,
  options options: LengthOptions,
) -> Result(Point, Error)

Return the subpath derivative at a traveled distance using explicit options.

pub fn subpath_directions(
  subpath: Subpath,
  at parameter: SubpathParameter,
) -> Result(Directions, Error)

Return singularity-safe unit traversal directions at a subpath parameter.

At internal vertices and closed seams, directions are taken from the adjacent segments. Directionless segments are skipped. Open subpath ends have only the side supplied by the subpath.

pub fn subpath_directions_with(
  subpath: Subpath,
  at parameter: SubpathParameter,
  options options: DirectionOptions,
) -> Result(Directions, Error)

Return singularity-safe unit traversal directions using explicit options.

pub fn subpath_distance(
  point: Point,
  to subpath: Subpath,
) -> Result(Float, Error)

Return the shortest distance from a point to a subpath.

pub fn subpath_distance_with(
  point: Point,
  to subpath: Subpath,
  options options: DistanceOptions,
) -> Result(Float, Error)

Return the shortest distance from a point to a subpath using explicit options.

pub fn subpath_empty(at start: Point) -> Subpath

Create an empty open subpath at a start point.

This represents a move-only subpath such as M 0 0.

pub fn subpath_end(subpath: Subpath) -> Point

Return the end point of a subpath.

pub fn subpath_from_parametric(
  from start: Float,
  to end: Float,
  point point_function: fn(Float) -> Point,
) -> Result(Subpath, Error)

Approximate a parametric curve with a sequence of cubic Bezier segments.

The parameter interval is split uniformly into default_parametric_options().initial_piece_count pieces. Each piece is fitted with a cubic, then recursively bisected in parameter space until the maximum sampled fitting error is within tolerance. from and to must be finite and unequal; descending intervals are allowed. Otherwise returns InvalidParametricInterval. Fitting and construction errors propagate; this function does not guarantee a successful fit.

pub fn subpath_from_parametric_with(
  from start: Float,
  to end: Float,
  point point_function: fn(Float) -> Point,
  options options: ParametricOptions,
) -> Result(Subpath, Error)

Approximate a parametric curve with a sequence of cubic Bezier segments using explicit options.

If options.tangent is Some(tangent_function), each cubic is constrained to match the endpoint tangent directions returned by that function. If it is None, control points are fitted from samples while the endpoints are fixed. The interval restrictions are the same as for subpath_from_parametric. Options must satisfy the constraints documented on ParametricOptions; invalid options, failed fits, and exhausted refinement return errors.

pub fn subpath_is_closed(subpath: Subpath) -> Bool

Check whether a subpath is closed.

pub fn subpath_is_empty(subpath: Subpath) -> Bool

Check whether a subpath has no segments (a move-only subpath).

pub fn subpath_is_zero_length(
  subpath: Subpath,
  tolerance tolerance: Float,
) -> Result(Bool, Error)

Return whether a subpath is a zero-length drawing subpath.

Empty subpaths are not considered zero-length drawing subpaths. A non-empty subpath is zero-length when every segment has length at most tolerance.

pub fn subpath_join(
  subpaths: List(Subpath),
) -> Result(Subpath, Error)

Join open subpaths into one open subpath.

Each subpath’s end point must exactly match the next subpath’s start point. Empty open subpaths can act as identity values when their start points line up with their neighbors.

pub fn subpath_join_with(
  subpaths: List(Subpath),
  policy endpoint_policy: EndpointPolicy,
) -> Result(Subpath, Error)

Join open subpaths using the given endpoint policy.

Returns EmptySubpath for an empty input list and AlreadyClosed if any input is closed. Follows subpath_join, except the policy may repair gaps; reconciliation errors propagate.

pub fn subpath_length(subpath: Subpath) -> Result(Float, Error)

Return the approximate length of a subpath.

Empty subpaths have length 0.0.

pub fn subpath_length_upper_bound(
  subpath: Subpath,
) -> Result(Float, Error)

Sum the cheap segment-length upper bounds of a subpath.

Empty subpaths return 0.0. The closed flag adds no implicit segment. See segment_length_upper_bound for the bounds and numerical limitations.

pub fn subpath_length_with(
  subpath: Subpath,
  options options: LengthOptions,
) -> Result(Float, Error)

Return the approximate length of a subpath using explicit options.

pub fn subpath_map_points(
  subpath: Subpath,
  with f: fn(Point) -> Point,
) -> Result(Subpath, Error)

Map the defining points of every segment in a subpath.

The subpath’s closed state is preserved. For nonlinear functions, this maps endpoints and control points, not the exact image of every point on each rendered curve. If any segment is an arc, this returns CannotMapArcNonlinearly.

pub fn subpath_normalize_zero_length_lines(
  subpath: Subpath,
) -> Subpath

Remove zero-length line segments from a subpath.

If cleanup would remove every segment, one zero-length line is preserved so a zero-length drawing subpath does not become a move-only subpath.

pub fn subpath_open(subpath: Subpath) -> Subpath

Open a subpath without changing its segments, endpoints, or traversal order.

Only the semantic closed flag is cleared. This cannot fail and does not reconcile endpoints. Empty and already-open subpaths are returned unchanged. Use subpath_open_at to choose a new start along a closed traversal.

pub fn subpath_open_at(
  subpath: Subpath,
  at parameter: SubpathParameter,
) -> Result(Subpath, Error)

Break open a closed subpath at the given subpath parameter.

The returned subpath is open and traverses the whole loop from the split point back to itself. The parameter must address a segment in the closed subpath, with t inside 0.0..1.0.

pub fn subpath_parameter_at_length(
  subpath: Subpath,
  distance distance: Float,
) -> Result(SubpathParameter, Error)

Return the subpath parameter at a traveled distance from the subpath start.

The distance is measured in path coordinate units, not normalized. The returned value is an ordinary public SubpathParameter.

pub fn subpath_parameter_at_length_with(
  subpath: Subpath,
  distance distance: Float,
  options options: LengthOptions,
) -> Result(SubpathParameter, Error)

Return the subpath parameter at a traveled distance using explicit options.

pub fn subpath_parameter_canonicalize(
  subpath: Subpath,
  parameter parameter: SubpathParameter,
) -> Result(SubpathParameter, Error)

Return the exact canonical address of a subpath parameter.

An exact internal segment end canonicalizes to the next segment’s t = 0.0. The exact end of a closed subpath’s last segment canonicalizes to SubpathParameter(0, 0.0). The end of an open subpath’s last segment remains at t = 1.0. Parameters merely near a boundary are unchanged. A local t = -0.0 canonicalizes to 0.0.

pub fn subpath_parameter_compare(
  a: SubpathParameter,
  b: SubpathParameter,
) -> order.Order

Compare two subpath parameters by segment index and then local t.

pub fn subpath_parameter_from_end(
  subpath: Subpath,
  segment_index segment_index: Int,
  t t: Float,
) -> Result(SubpathParameter, Error)

Return a validated subpath parameter addressed as if the subpath were reversed.

segment_index addresses the reversed segment list. t is also measured in the reversed segment’s direction, then converted back into the original subpath’s coordinates.

pub fn subpath_parameter_snap_to_boundary(
  subpath: Subpath,
  parameter parameter: SubpathParameter,
  tolerance tolerance: Float,
) -> Result(SubpathParameter, Error)

Snap a subpath parameter to a segment boundary in parameter space, then return its canonical address.

tolerance is measured in the addressed segment’s local parameter units, not in path coordinate units. It must be finite and greater than zero.

pub fn subpath_point(
  subpath: Subpath,
  at parameter: SubpathParameter,
) -> Result(Point, Error)

Evaluate a subpath at a subpath parameter.

The parameter must address a segment in the subpath, with t inside 0.0..1.0. Internal segment-end parameters are evaluated through their canonical next-segment start address.

pub fn subpath_point_at_length(
  subpath: Subpath,
  distance distance: Float,
) -> Result(Point, Error)

Return the subpath point at a traveled distance from the subpath start.

pub fn subpath_point_at_length_with(
  subpath: Subpath,
  distance distance: Float,
  options options: LengthOptions,
) -> Result(Point, Error)

Return the subpath point at a traveled distance using explicit options.

pub fn subpath_polygon(
  points: List(Point),
) -> Result(Subpath, Error)

Create a closed subpath connecting the given points with line segments.

The input must contain at least two points. If the last point equals the first point, no extra zero-length closing line is added.

This is equivalent to constructing a subpath_polyline from the same points and closing it with subpath_close_with(..., policy: Bridge).

pub fn subpath_polyline(
  points: List(Point),
) -> Result(Subpath, Error)

Create an open subpath connecting the given points with line segments.

The input must contain at least two points.

pub fn subpath_projection(
  point: Point,
  to subpath: Subpath,
) -> Result(SubpathProjection, Error)

Return the nearest point on a subpath to an input point.

pub fn subpath_projection_with(
  point: Point,
  to subpath: Subpath,
  options options: DistanceOptions,
) -> Result(SubpathProjection, Error)

Return the nearest point on a subpath to an input point using explicit options.

pub fn subpath_rebuild_with(
  subpath: Subpath,
  policy endpoint_policy: EndpointPolicy,
) -> Result(Subpath, Error)

Rebuild a subpath using an endpoint policy.

This re-runs endpoint reconciliation on the subpath’s current segment list and preserves the subpath’s open/closed state. Empty subpaths are preserved unchanged.

pub fn subpath_remap_endpoints(
  subpath: Subpath,
  new_start new_start: Point,
  new_end new_end: Point,
) -> Result(Subpath, Error)

Remap a subpath so its current endpoints become new_start and new_end.

Empty subpaths keep their empty segment list and move to new_start.

pub fn subpath_reverse(subpath: Subpath) -> Subpath

Reverse the traversal direction of every segment in a subpath.

The subpath’s closed state is preserved.

pub fn subpath_second_derivative(
  subpath: Subpath,
  at parameter: SubpathParameter,
) -> Result(Point, Error)

Return a subpath’s segment second derivative at a subpath parameter.

The parameter must address a segment in the subpath, with t inside 0.0..1.0. Internal segment-end parameters are evaluated through their canonical next-segment start address.

pub fn subpath_segments(subpath: Subpath) -> List(Segment)

Return the segments in a subpath.

pub fn subpath_splice(
  subpath: Subpath,
  start start: Int,
  delete delete: Int,
  insert insert: List(Segment),
) -> Result(Subpath, Error)

Replace a range of segments in a subpath.

start is a zero-based segment index and delete is the number of segments to remove. If start + delete extends past the end of the subpath, everything from start onward is deleted. Negative start, negative delete, and start greater than the subpath length return InvalidSplice.

The edited subpath must remain continuous. Closed subpaths preserve their closed state. If the splice result is nonempty, the subpath start is updated to the first resulting segment’s start point. If the splice result is empty, the previous start point is preserved.

pub fn subpath_splice_with(
  subpath: Subpath,
  start start: Int,
  delete delete: Int,
  insert insert: List(Segment),
  policy endpoint_policy: EndpointPolicy,
) -> Result(Subpath, Error)

Replace a range of segments in a subpath using the given endpoint policy.

Index, deletion, start-point, and closure rules are those of subpath_splice. The policy reconciles resulting boundaries; errors from that reconciliation propagate, including violations of the EndpointPolicy custom contract.

pub fn subpath_split(
  subpath: Subpath,
  at at: SubpathParameter,
) -> Result(#(Subpath, Subpath), Error)

Split an open subpath at a subpath parameter.

The split point must be inside the subpath: it cannot be the first point, the last point, outside the segment list, or outside the addressed segment’s 0.0..1.0 parameter range. Closed and empty subpaths are rejected.

pub fn subpath_start(subpath: Subpath) -> Point

Return the start point of a subpath.

pub fn subpath_subdivide_to_max_length(
  subpath: Subpath,
  max_length max_length: Float,
) -> Result(Subpath, Error)

Subdivide every segment in a subpath into pieces of at most max_length.

Existing segment boundaries are preserved. The subpath’s closed state is preserved.

pub fn subpath_subdivide_to_max_length_with(
  subpath: Subpath,
  max_length max_length: Float,
  options options: LengthOptions,
) -> Result(Subpath, Error)

Subdivide every segment in a subpath into pieces of at most max_length using explicit length options.

pub fn subpath_to_cubic_beziers(subpath: Subpath) -> Subpath

Convert every segment in a subpath to cubic Bezier curves.

Lines and quadratic Beziers are converted exactly. Cubic Beziers are preserved. Elliptical arcs are approximated with one or more cubic Beziers, split into chunks of at most a quarter turn.

pub fn subpath_to_lines(
  subpath: Subpath,
) -> Result(Subpath, Error)

Approximate every segment in a subpath with straight lines.

The subpath’s start point and closed state are preserved. Move-only subpaths remain move-only.

pub fn subpath_to_lines_with(
  subpath: Subpath,
  options options: LinearizeOptions,
) -> Result(Subpath, Error)

Approximate every segment in a subpath with straight lines using explicit options.

pub fn subpath_try_map_points(
  subpath: Subpath,
  with f: fn(Point) -> Result(Point, error),
) -> Result(Subpath, PointMapError(error))

Map the defining points of every segment in a subpath with a fallible function.

This has the same geometry semantics as subpath_map_points, but the mapping function may reject individual points.

pub fn subpath_with(
  segments: List(Segment),
  policy endpoint_policy: EndpointPolicy,
) -> Result(Subpath, Error)

Create an open subpath using the given endpoint reconciliation policy.

Empty segment lists still return EmptySubpath. Other construction rules are those of subpath, except that policy may repair endpoint gaps. Returns an error if the policy cannot reconcile a boundary or a custom replacement violates the EndpointPolicy contract.

pub fn wiggle_else_bridge_with(
  tolerance: Float,
) -> EndpointPolicy

Create a wiggle-else-bridge endpoint policy with a custom distance tolerance.

pub fn wiggle_with(tolerance: Float) -> EndpointPolicy

Create a wiggle endpoint policy with a custom distance tolerance.

Search Document