# Path

A representation of a two-dimensional path made up of straight and curved segments.

## Constructors

Path(anchors,closed,stroke,fill)→[Path](https://cuttle.xyz/learn/reference/Path)

Constructs a path from an array of anchors.

`anchors`

`[Anchor](https://cuttle.xyz/learn/reference/Anchor)[]`

`[]`

An array of anchors

`closed`

`boolean`

`false`

If `true`, the path will form a loop

`stroke`

`[Stroke](https://cuttle.xyz/learn/reference/Stroke)`

optional

A stroke style to assign

`fill`

`([Fill](https://cuttle.xyz/learn/reference/Fill) | [ImageFill](https://cuttle.xyz/learn/reference/ImageFill))`

optional

A fill style to assign

Path.fromPoints(points,closed)→[Path](https://cuttle.xyz/learn/reference/Path)

Connects a series of points with lines to form a path.

`points`

`[Vec](https://cuttle.xyz/learn/reference/Vec)[]`

`closed`

`boolean`

`false`

Path.fromCubicBezierPoints(points,closed)→[Path](https://cuttle.xyz/learn/reference/Path)

Constructs a path from an array of points interpreted as cubic bezier positions.

In canvas-style drawing terms, the first point is interpreted as a "move to" command. Subsequent groups of 3 points are interpreted as "curve to" commands.

`points`

`[Vec](https://cuttle.xyz/learn/reference/Vec)[]`

`closed`

`boolean`

`false`

Path.fromSegment(segment)→[Path](https://cuttle.xyz/learn/reference/Path)

Constructs a path from a segment.

`segment`

`([LineSegment](https://cuttle.xyz/learn/reference/LineSegment) | [CubicSegment](https://cuttle.xyz/learn/reference/CubicSegment))`

Path.fromFragments(fragments)→[Path](https://cuttle.xyz/learn/reference/Path)

Constructs a path from a sequence of path fragments.

If sequential fragments are connected -- the second fragment starts from the position where the previous fragment ended -- they will be merged together. Otherwise, a line will be drawn in-between.

If the start and end points of the entire sequence are equal, the resulting path will be closed.

`fragments`

`([LineSegment](https://cuttle.xyz/learn/reference/LineSegment) | [CubicSegment](https://cuttle.xyz/learn/reference/CubicSegment) | [Path](https://cuttle.xyz/learn/reference/Path) | [Anchor](https://cuttle.xyz/learn/reference/Anchor))[]`

Path.fromBoundingBox(box)→[Path](https://cuttle.xyz/learn/reference/Path)

Constructs a path from a bounding box.

`box`

`[BoundingBox](https://cuttle.xyz/learn/reference/BoundingBox)`

Returns A clockwise closed path

Path.fromArc(center,radius,startAngle,endAngle)→[Path](https://cuttle.xyz/learn/reference/Path)

Constructs an arc (circle segment) path.

`center`

`[Vec](https://cuttle.xyz/learn/reference/Vec)`

`radius`

`number`

`startAngle`

`number`

The angle at the start of the arc, specified in degrees

`endAngle`

`number`

The angle at the end of the arc, specified in degrees

To construct a clockwise arc, `endAngle` must be greater than `startAngle`. If `endAngle` is less than `startAngle`, add 360° to draw a clockwise arc. For counter-clockwise, do the opposite.

```
if (endAngle < startAngle) {
  endAngle += 360;
}
```

Path.fromSmoothFunction(func,domainStart,domainEnd,tolerance)→[Path](https://cuttle.xyz/learn/reference/Path)

Constructs a path that plots a smooth function over a given time domain.

It's important that `func` be a smooth function for this to produce a path. A smooth function must be continuous and should have C1 differentiability (continuous derivative).

See: [https://en.wikipedia.org/wiki/Smoothness](https://en.wikipedia.org/wiki/Smoothness)

`func`

The function to plot, taking a single argument "time"

`domainStart`

`number`

Start of the time domain to evaluate the function over

`domainEnd`

`number`

End of the time domain to evaluate the function over

`tolerance`

`number`

The resulting path will be considered "close enough" if it is within this distance from the true plot.

## Properties

.anchors[Anchor](https://cuttle.xyz/learn/reference/Anchor)\[\]

An array of anchors that makes up the path.

.closedboolean

Specifies if the path is closed. If closed, the first and last anchors will be connected by an additional segment.

.stroke[Stroke](https://cuttle.xyz/learn/reference/Stroke)optional

The stroke style

.fill([Fill](https://cuttle.xyz/learn/reference/Fill) | [ImageFill](https://cuttle.xyz/learn/reference/ImageFill))optional

The fill style

## Methods

.segments()→([LineSegment](https://cuttle.xyz/learn/reference/LineSegment) | [CubicSegment](https://cuttle.xyz/learn/reference/CubicSegment))\[\]

Returns an array of segments for the path.

.segmentPaths()→[Path](https://cuttle.xyz/learn/reference/Path)\[\]

Returns an array of paths corresponding to each segment in the path.

.edgePaths()→[Path](https://cuttle.xyz/learn/reference/Path)\[\]

A path can be broken into edges by splitting it at every corner. A corner is an anchor with non-tangent handles. This means each edge will be a path that is "smooth", i.e. all of its anchors have tangent handles.

Returns an array of edges for the path.

.length()→number

Returns the approximate arc length of the path.

.signedArea()→number

Returns the signed area of the path. Clockwise paths will have a positive area and counter-clockwise paths negative. Paths are assumed to be non-intersecting. Paths such as infinity (∞) that cross over themselves will have both positive and negative areas which will cancel out and give an incorrect result.

.area()→number

Returns the area of the path. Paths such as infinity (∞) that cross over themselves will have both positive and negative areas which will cancel out and give an incorrect result.

.timeAtDistance(distance)→number

`distance`

`number`

A positive distance

Returns the approximate time at `distance` along the path.

If `distance` is greater than the length of the path, this will return the time of the last anchor.

.distanceAtTime(time)→number

`time`

`number`

A valid path time

Returns the approximate distance along the path at `time`.

.normalizedTime(time)→number

`time`

`number`

A valid path time

Returns the canonical time for `time`.

If the path is closed, time will loop.

.isSameTime(time1,time2)→boolean

`time1`

`number`

`time2`

`number`

Returns `true` if `time1` and `time2` correspond to the same normalized path time.

.firstAnchor()→[Anchor](https://cuttle.xyz/learn/reference/Anchor)

Returns the first anchor at the start of the path.

.lastAnchor()→[Anchor](https://cuttle.xyz/learn/reference/Anchor)

Returns the last anchor at the end of the path.

.endTime()→number

Returns the time that corrensponds to the end of the path. This is different for closed paths to account for the closing segment.

.mixedTime(time1,time2,t)→number

`time1`

`number`

The time when the mixing factor is 0

`time2`

`number`

The time when the mixing factor is 1

`t`

`number`

The mixing factor

Returns a time in-between `time1` and `time2`. If the path is closed, return a time in the shorter of the two possible spans.

.isCorner(time)→boolean

`time`

`number`

A valid path time

Returns `true` if the point at `time` is a corner, meaning that there is an anchor at `time` that does not have tangent handles or is an endpoint.

Note: this currently counts any anchor with zeroed handles as a corner, even if it's a 180 degree anchor.

.isSmooth()→boolean

Returns `true` if all non-endpoint anchors have tangent handles.

.isEndpoint(time)→boolean

`time`

`number`

A valid path time

Returns `true` if the point at `time` is an endpoint of the path.

Note that this will always return `false` for closed paths since they have no endpoints.

.anchorAtTime(time)→[Anchor](https://cuttle.xyz/learn/reference/Anchor)

`time`

`number`

Returns the anchor at or before `time`.

.segmentAtTime(time)→([LineSegment](https://cuttle.xyz/learn/reference/LineSegment) | [CubicSegment](https://cuttle.xyz/learn/reference/CubicSegment))

`time`

`number`

A valid path time

Returns the segment that contains the point at `time`.

When called on open paths with `time` at its maximum, the last segment will be returned.

.positionAtTime(time)→[Vec](https://cuttle.xyz/learn/reference/Vec)

`time`

`number`

A valid path time

Returns the position on the path at `time`.

.derivativeAtTime(time)→[Vec](https://cuttle.xyz/learn/reference/Vec)

`time`

`number`

A valid path time

Returns the first derivative of the path at `time`.

.secondDerivativeAtTime(time)→[Vec](https://cuttle.xyz/learn/reference/Vec)

`time`

`number`

A valid path time

Returns the second derivative of the path at `time`.

The second derivative can also be thought of as the "acceleration", or change in velocity of a point moving along the curve.

.curvatureAtTime(time)→number

`time`

`number`

A valid path time

Returns the curvature of the path at `time`.

Curvature describes how "bent" a path is at a given point. It can be thought of as the reciprocal of the radius of a circle with the same curvature. To find the radius, one can use the formula `1 / curvature`.

.tangentAtTime(time)→[Vec](https://cuttle.xyz/learn/reference/Vec)

`time`

`number`

A valid path time

Returns a unit-length vector tangent to the path at `time`.

.normalAtTime(time)→[Vec](https://cuttle.xyz/learn/reference/Vec)

`time`

`number`

A valid path time

Returns a unit-length vector perpendicular to the path at `time`.

.angleAtTime(time)→number

`time`

`number`

A valid path time

Returns the angle of of the tangent to the path at `time`.

.insertAnchorAtTime(time)→([Anchor](https://cuttle.xyz/learn/reference/Anchor) | undefined)

Attempts to insert an anchor into the path at `time`.

`time`

`number`

A valid path time

Returns the inserted anchor, or `undefined` if there already was an anchor at `time`

.splitAtAnchor(anchor)→(\[[Path](https://cuttle.xyz/learn/reference/Path)\] | \[[Path](https://cuttle.xyz/learn/reference/Path), [Path](https://cuttle.xyz/learn/reference/Path)\])

Splits the path at a specific `anchor`.

`anchor`

`[Anchor](https://cuttle.xyz/learn/reference/Anchor)`

An anchor contained within the path

Returns Two open paths if the path is already open, or one open path if the path is closed

Note: Paths returned from this method will share references to anchors in the original path.

.splitAtTime(time)→(\[[Path](https://cuttle.xyz/learn/reference/Path)\] | \[[Path](https://cuttle.xyz/learn/reference/Path), [Path](https://cuttle.xyz/learn/reference/Path)\])

Splits the path at a specific `time`.

`time`

`number`

A valid path time

Returns two open paths if the path is already open, or one open path if the path is closed.

Note: Paths returned from this method will share references to anchors in the original path.

.splitAtTimes(times)→[Path](https://cuttle.xyz/learn/reference/Path)\[\]

Splits the path in one or more places.

The first path will always be the one _before_ the first split point.

`times`

`number[]`

An array of path times

Returns One or more paths, depending on the number of split times.

.roundCorners(radius)→[Path](https://cuttle.xyz/learn/reference/Path)chainable

Replaces sharp corners in the path with circular arcs of `radius`.

`radius`

`(number | number[])`

A positive number

.roundCornerAtAnchor(anchor,radius)→[Path](https://cuttle.xyz/learn/reference/Path)chainable

Replaces a sharp corner with a circular arc of `radius` at a specific anchor.

`anchor`

`[Anchor](https://cuttle.xyz/learn/reference/Anchor)`

The anchor to replace

`radius`

`number`

A positive number

.slice(startTime,endTime)→[Path](https://cuttle.xyz/learn/reference/Path)

`startTime`

`number`

A valid path time

`endTime`

`number`

A valid path time greater than `startTime`

Returns A new path that is the subset of the path between `startTime` and `endTime`.

.splice(orderedSplices)→[Path](https://cuttle.xyz/learn/reference/Path)chainable

Cuts the path and inserts each splice `path` between `time1` and `time2`.

Splices are assumed to be non-overlapping and ordered such that `time2` is greater than `time1` and time values increase monotonically when forward-iterating through the array. Splice paths are assumed to connect at their first and last anchors sequentially.

`orderedSplices`

`[]`

.smooth()→[Path](https://cuttle.xyz/learn/reference/Path)chainable

Makes all anchor handles tangent, ensuring the path is fully smooth.

-   If both handles exist, their angles are averaged.
-   If one handle is zero, it mirrors the other.
-   If both handles are zero, the tangent is set perpendicular to the angle bisector of the neighboring anchors, with handle lengths set to 1/3 the distance to each neighbor.
-   Handles at the endpoints of open paths are not modified.

.warpCoordinates(mappingFunc,tolerance)→[Path](https://cuttle.xyz/learn/reference/Path)chainable

Warps this path using a mapping function.

`mappingFunc`

A function that maps a point in the original space to a point in the warped space

`tolerance`

`number`

The maximum distance between the original and warped paths, which determines how closely the warped path should follow the original path.

.mergeAnchors(mergeDistance)→[Path](https://cuttle.xyz/learn/reference/Path)chainable

Merges contiguous anchors of this path that are less than some distance apart from each other.

`mergeDistance`

`number`

`DEFAULT_TOLERANCE`

A small threshold distance. Anchors closer than this will be merged together.

## Methods inherited from [Geometry](https://cuttle.xyz/learn/reference/Geometry)

.transform(transform)→thischainable

Transforms this geometry.

A transform can optionally specify any of `position`, `rotation`, `scale`, `skew` and `origin`.

`origin` defines the center (in pre-transform coordinates) of the transformation for `rotation`, `scale` and `skew`.

```
// Simple translation
geometry.translate({
  position: Vec(1, 0),
});

// Rotation and scale
geometry.transform({
  rotation: 45,
  scale: 2,
});

// Complicated transform
geometry.transform({
  position: Vec(1, 1),
  rotation: 180,
  scale: Vec(2, 1),
  skew: 45,
  origin: Vec(-0.5, 0.5),
};
```

`transform`

`[TransformArgs](https://cuttle.xyz/learn/reference/interfaces#TransformArgs)`

.intersectionsWith(geometries,areaOfInterest)→[IntersectionResult](https://cuttle.xyz/learn/reference/interfaces#IntersectionResult)\[\]

`geometries`

`[Geometry](https://cuttle.xyz/learn/reference/Geometry)[]`

An array of geometries to intersect with.

`areaOfInterest`

`[BoundingBox](https://cuttle.xyz/learn/reference/BoundingBox)`

optional

If supplied, only intersection results inside this bounding box will be returned. This can save a lot of computation if you only need to find intersections within a small area.

Returns An array of intersections between this geometry and `geometries`

.overlapsWith(geometries,areaOfInterest,tolerance)→[OverlapResult](https://cuttle.xyz/learn/reference/OverlapResult)\[\]

`geometries`

`[Geometry](https://cuttle.xyz/learn/reference/Geometry)[]`

An array of geometries to find overlaps with.

`areaOfInterest`

`[BoundingBox](https://cuttle.xyz/learn/reference/BoundingBox)`

optional

If supplied, input geometry will be filtered so that only parts that intersect this bounding box will be tested. This can save a lot of time if only need to find overlaps within a small area.

`tolerance`

`number`

optional

The maximum distance apart two segments can be to be considered overlapping.

Returns An array of overlaps between this geometry and `geometries`

.distanceToIntersect(targetGeometry,direction,options)→(number | undefined)

`targetGeometry`

`[Geometry](https://cuttle.xyz/learn/reference/Geometry)`

The geometry to move toward.

`direction`

`[Vec](https://cuttle.xyz/learn/reference/Vec)`

The direction to move in. This should point towards the target geometry, otherwise no intersection may be found.

`options`

`[DistanceToIntersectOptions](https://cuttle.xyz/learn/reference/interfaces#DistanceToIntersectOptions)`

optional

Returns approximately the smallest distance to move until this geometry intersects the target geometry.

If `minOverlap` is specified, the distance to move until the geometry overlaps by some minimum width will be returned instead.

Returns `undefined` if no intersection is found.

.clone()→[Path](https://cuttle.xyz/learn/reference/Path)

Clone is useful when you need to make a change to geometry without changing the original.

```
const transformedPath = path.clone().transform({ rotation: 45 });
```

Returns A deep copy of this geometry

.isValid()→boolean

Returns `true` if this geometry is valid, or `false` otherwise.

.affineTransform(affineMatrix)→[Path](https://cuttle.xyz/learn/reference/Path)chainable

Spatially transforms this geometry by an affine transformation matrix.

Affine matrices can represent any 2-dimensional transformation that keeps lines parallel.

`affineMatrix`

`[AffineMatrix](https://cuttle.xyz/learn/reference/AffineMatrix)`

.affineTransformWithoutTranslation(affineMatrix)→[Path](https://cuttle.xyz/learn/reference/Path)chainable

Spatially transforms this geometry by an affine transformation matrix, excluding translation. Only rotation, scale, and skew transformations will be applied.

`affineMatrix`

`[AffineMatrix](https://cuttle.xyz/learn/reference/AffineMatrix)`

.looseBoundingBox()→([BoundingBox](https://cuttle.xyz/learn/reference/BoundingBox) | undefined)

The loose bounding box may not be the smallest possible, but it's usually cheaper to compute. Use this when the exact bounding box isn't required.

Returns an axis-aligned bounding box that contains this geometry.

.boundingBox()→([BoundingBox](https://cuttle.xyz/learn/reference/BoundingBox) | undefined)

Returns the smallest axis-aligned bounding box that contains this geometry.

.isContainedByBoundingBox(box)→boolean

Geometry is contained by a bounding box if no part of it lies beyond it's minimum and maximum.

`box`

`[BoundingBox](https://cuttle.xyz/learn/reference/BoundingBox)`

.isIntersectedByBoundingBox(box)→boolean

Geometry intersects a bounding box if part of the geometry crosses the boundary between the inside and outside of the box.

`box`

`[BoundingBox](https://cuttle.xyz/learn/reference/BoundingBox)`

.isOverlappedByBoundingBox(box)→boolean

Geometry is overlapped by a bounding box if a point can be chosen that is indside both the geometry and the box.

Geometry is overlapped by a bounding box if it's contained inside, or intersected by it.

`box`

`[BoundingBox](https://cuttle.xyz/learn/reference/BoundingBox)`

.reverse()→[Path](https://cuttle.xyz/learn/reference/Path)chainable

Reverses this geometry.

.closestPoint(point,areaOfInterest)→([ClosestPointResultWithTime](https://cuttle.xyz/learn/reference/interfaces#ClosestPointResultWithTime) | undefined)

`point`

`[Vec](https://cuttle.xyz/learn/reference/Vec)`

The target point

`areaOfInterest`

`[BoundingBox](https://cuttle.xyz/learn/reference/BoundingBox)`

optional

If supplied, only results inside this bounding box will be returned. This can save a lot of computation if you only need to find closest points within a small area. Typically `areaOfInterest` is centered on `point`, but this isn't required.

Returns The closest point to `point` that lies on this geometry, or `undefined` if no point is found.

.isValid(a)→

`a`

`unknown`

Returns `true` if `graphic` is a valid graphic

## Methods inherited from [Graphic](https://cuttle.xyz/learn/reference/Graphic)

.allCompoundPaths()→[CompoundPath](https://cuttle.xyz/learn/reference/CompoundPath)\[\]

Returns all compound paths contained within this graphic, recursively.

.allPathsByColor()→[Path](https://cuttle.xyz/learn/reference/Path)\[\]\[\]

Returns all paths grouped by their stroke and fill colors.

Paths must have identical stroke _and_ fill colors to be grouped together.

.allPaths()→[Path](https://cuttle.xyz/learn/reference/Path)\[\]

Returns all paths contained within this graphic, recursively.

.allAnchors()→[Anchor](https://cuttle.xyz/learn/reference/Anchor)\[\]

Returns all anchors contained within this graphic, recursively.

.allPathsAndCompoundPaths()→[Path](https://cuttle.xyz/learn/reference/Path)\[\]

Returns all paths and compound paths contained within this graphic, recursively.

.hasStyle()→boolean

Returns `true` if this graphic has either a stroke or a fill.

.assignFill(fill)→[Path](https://cuttle.xyz/learn/reference/Path)chainable

Assigns a fill to this graphic.

`fill`

`([Fill](https://cuttle.xyz/learn/reference/Fill) | [ImageFill](https://cuttle.xyz/learn/reference/ImageFill))`

.removeFill()→[Path](https://cuttle.xyz/learn/reference/Path)chainable

Removes a fill style from this graphic.

.assignStroke(stroke)→[Path](https://cuttle.xyz/learn/reference/Path)chainable

Assigns a stroke style to this graphic.

`stroke`

`[Stroke](https://cuttle.xyz/learn/reference/Stroke)`

.removeStroke()→[Path](https://cuttle.xyz/learn/reference/Path)chainable

Removes a stroke style from this graphic.

.assignStyle(fill,stroke)→[Path](https://cuttle.xyz/learn/reference/Path)chainable

Assigns both a stroke and fill style to this graphic.

`fill`

`[Fill](https://cuttle.xyz/learn/reference/Fill)`

`stroke`

`[Stroke](https://cuttle.xyz/learn/reference/Stroke)`

.copyStyle(graphic)→[Path](https://cuttle.xyz/learn/reference/Path)chainable

Copies the stroke and fill from `graphic`.

`graphic`

`[Graphic](https://cuttle.xyz/learn/reference/Graphic)`

.scaleStroke(scaleFactor)→[Path](https://cuttle.xyz/learn/reference/Path)chainable

Scales the stroke width of this graphic by `scaleFactor`.

`scaleFactor`

`number`

The amount to scale existing strokes by

.firstStyled()→([Path](https://cuttle.xyz/learn/reference/Path) | undefined)

Returns The first styled graphic (Path or CompoundPath) in a group, or the styled path itself. A path must have either a stroke or fill to be considered styled.

.containsPoint(point)→boolean

Returns `true` if this graphic contains `point`.

`point`

`[Vec](https://cuttle.xyz/learn/reference/Vec)`

The point to test

.styleContainsPoint(point)→boolean

Returns `true` if this graphic's style contains `point`.

This method differs from `containsPoint()` in that it takes the stroke and fill styling into account.

`point`

`[Vec](https://cuttle.xyz/learn/reference/Vec)`

The point to test1