Skip to main content

Curve

constructor

g.Curve(p1 [, p2, p3, p4])

Return a new curve object with start at point p1, control points at p2 and p3, and end at p4. All points are passed through the Point constructor so they can also be passed in string form. Examples:

var c = new g.Curve(new g.Point(10, 10), new g.Point(10, 40), new g.Point(50, 40), new g.Point(50, 10));
var c = new g.Curve('10 10', '10 40', '50 40', '50 10');
var c = new g.Curve('10@10', '10@40', '50@40', '50@10');

The constructor also accepts a single Curve object as an argument; it creates a new curve with points cloned from the provided curve.

Methods

bbox()

curve.bbox()

Return a rectangle that is the tight bounding box of the curve (i.e. not including the curve control points).

clone()

curve.clone()

Return another curve which is a clone of the curve.

closestPoint()

curve.closestPoint(point [, opt])

Return the point on the curve that lies closest to point.

The function uses the same algorithm as the curve.closestPointT() function. The point at t closest to point is returned.

The default value for opt.precision is 3; this corresponds to maximum observed error of 0.1%.

The opt.subdivisions property may be specified, directly providing an array of pre-computed curve subdivisions with which to begin the algorithm. Use the curve.getSubdivisions() function to obtain an array of curve subdivisions. The opt.precision property is still necessary, however; it determines the precision of the point search algorithm.

closestPointLength()

curve.closestPointLength(point [, opt])

Return the length of the curve up to the point that lies closest to point.

The function uses the same algorithm as the curve.closestPointT() function. The length of the curve at t closest to point is returned.

The default value for opt.precision is 3; this corresponds to maximum observed error of 0.1%.

The opt.subdivisions property may be specified, directly providing an array of pre-computed curve subdivisions with which to begin the algorithm. Use the curve.getSubdivisions() function to obtain an array of curve subdivisions. The opt.precision property is still necessary, however; it determines the precision of the point search algorithm.

closestPointNormalizedLength()

curve.closestPointNormalizedLength(point [, opt])

Return the normalized length (distance from the start of the curve / total curve length) of the curve up to the point that lies closest to point.

The function uses the same algorithm as the curve.closestPointT() function. The normalized length of the curve at t closest to point is returned.

The default value for opt.precision is 3; this corresponds to maximum observed error of 0.1%.

The opt.subdivisions property may be specified, directly providing an array of pre-computed curve subdivisions with which to begin the algorithm. Use the curve.getSubdivisions() function to obtain an array of curve subdivisions. The opt.precision property is still necessary, however; it determines the precision of the point search algorithm.

closestPointT()

curve.closestPointT(point [, opt])

Return the t value of the point on the curve that lies closest to point.

The curve is first subdivided, according to opt.precision (refer to curve.length() documentation for more information about precision and curve flattening). Then, one subdivision is identified whose endpoints are the closest to point. A binary search is then performed on that subdivision, until a curve is found whose diffrence between endpoints' distance to point lies within opt.precision. The t value of the closest endpoint is returned by the function.

The default value for opt.precision is 3; this corresponds to maximum observed error of 0.1%.

The opt.subdivisions property may be specified, directly providing an array of pre-computed curve subdivisions with which to begin the algorithm. Use the curve.getSubdivisions() function to obtain an array of curve subdivisions. The opt.precision property is still necessary, however; it determines the precision of the point search algorithm.

closestPointTangent()

curve.closestPointTangent(point [, opt])

Return a line that is tangent to the curve at the point that lies closest to point.

The tangent line starts at the identified closest point. The direction from start to end is the same as the direction of the curve at the closest point.

If the control points of the curve all lie at the same coordinates, null is returned (it is impossible to determine the slope of a point). The curve.isDifferentiable() function may be used in advance to determine whether tangents can exist for a given curve.

The function uses the same algorithm as the curve.closestPointT() function. The tangent at t closest to point is returned.

The default value for opt.precision is 3; this corresponds to maximum observed error of 0.1%.

The opt.subdivisions property may be specified, directly providing an array of pre-computed curve subdivisions with which to begin the algorithm. Use the curve.getSubdivisions() function to obtain an array of curve subdivisions. The opt.precision property is still necessary, however; it determines the precision of the point search algorithm.

containsPoint()

curve.containsPoint(p [, opt])

Return true if the point p is inside the area surrounded by the curve (inclusive). Return false otherwise. Uses the even-odd algorithm to resolve self-intersections.

Uses the curve.toPolyline() function in the background. The precision of the calculation may be adjusted by passing the opt.precision and opt.subdivisions properties.

divideAt()

curve.divideAt(ratio [, opt])

Divide the curve into two curves at the point that lies ratio (normalized length) away from the beginning of the curve.

Returns an array with two new curves without modifying the original curve. The function expects ratio to lie between 0 and 1; values outside the range are constrained to 0 and 1, respectively.

This function mirrors the functionality of the line.divideAt() function. If it is necessary to divide the curve at a certain t value instead, use the curve.divideAtT() function.

The function uses the same algorithm as the curve.divideAtLength() function.

The default value for opt.precision is 3; this corresponds to maximum observed error of 0.1%.

The opt.subdivisions property may be specified, directly providing an array of pre-computed curve subdivisions from which to calculate curve length. Use the curve.getSubdivisions() function to obtain an array of curve subdivisions. The opt.precision property is still necessary, however; it determines the precision of the point search algorithm.

divideAtLength()

curve.divideAtLength(length [, opt])

Divide the curve into two curves at the point that lies length away from the beginning of the curve.

Returns an array with two new curves without modifying the original curve. If negative length is provided, the algorithm starts looking from the end of the curve. If length is higher than curve length, the curve is divided at the closest endpoint instead.

The curve is first subdivided, according to opt.precision (refer to curve.length() documentation for more information about precision and curve flattening). Then, one subdivision is identified which contains the point at length. A binary search is then performed on that subdivision, until a curve is found whose endpoint lies within opt.precision away from length. That endpoint is used by the function to divide the curve.

The default value for opt.precision is 3; this corresponds to maximum observed error of 0.1%.

As a rule of thumb, increasing precision by 1 doubles the number of operations needed to find the point to be returned (this is on top of the cost of curve subdivision); exact numbers vary for every individual curve, however.

The opt.subdivisions property may be specified, directly providing an array of pre-computed curve subdivisions from which to calculate curve length. Use the curve.getSubdivisions() function to obtain an array of curve subdivisions. The opt.precision property is still necessary, however; it determines the precision of the point search algorithm.

divideAtT()

curve.divideAtT(t)

Divide the curve into two curves at the point specified by t.

Returns an array with two new curves without modifying the original curve. The function expects t to lie between 0 and 1; values outside the range are constrained to 0 and 1, respectively.

This function is not a counterpart to the line.divideAt() function. The relationship between t and distance along a curve is complex and non-linear. If it is necessary to divide the curve at a certain ratio (normalized length) away from beginning of the curve, use the curve.divideAt() function.

endpointDistance()

curve.endpointDistance()

Return the distance between curve start and end points.

equals()

curve.equals(otherCurve)

Return true if the curve exactly equals the other curve.

getSkeletonPoints()

curve.getSkeletonPoints(t)

Return an object that contains five points necessary for dividing curves.

The function expects t to lie between 0 and 1; values outside the range are constrained to 0 and 1, respectively.

The returned object has the following properties:

startControlPoint1First curve's controlPoint1.
startControlPoint2First curve's controlPoint2.
dividerThe point at t; end point of the first curve and start point of the second curve.
dividerControlPoint1Second curve's controlPoint1.
dividerControlPoint2Second curve's controlPoint2

If only the point at t is needed, use the curve.pointAtT() function.

If the two divided curves are needed, rather than their control points, use the curve.divideAtT() function.

getSubdivisions()

curve.getSubdivisions([opt])

Return an array of curves obtained by recursive halving of the curve up to a given precision.

Halving is not defined in terms of length, but in terms of the t parameter. The curves are subdivided at t = 0.5.

This is an intermediary function. Curve functions that rely on length calculations must work with flattened curves, with points obtained by curve subdivision at an arbitrary precision level. Refer to curve.length() documentation for more information about precision and curve flattening.

This function makes it possible to avoid expensive re-subdivisions of the curve when several operations need to be performed at the same level of precision (for example, obtaining the length of the curve and then finding the point at 10% length). The returned array may be passed to all such functions as the opt.subdivisions property.

The default value for opt.precision is 3; this corresponds to maximum observed error of 0.1%.

isDifferentiable()

curve.isDifferentiable()

Return true if a tangent line can be found for the curve.

Tangents cannot be found if all of the curve control points are coincident (the curve appears to be a point).

length()

curve.length([opt])

Return the length of the curve.

The curve length is a flattened length. This means that there will always be a difference between the reported length and the real length of the curve. (The returned curve length is always lower than the actual curve length.) That being said, the observed error can be constrained to an arbitrary threshold - here determined by opt.precision.

The opt.precision property is logarithmic, which means that increasing precision by 1 decreases observed error in length by a factor of 10. (For example, precision 3 leads to an observed error of less than 0.1%, precision 4 guarantees an observed error of less than 0.01%, etc.)

The default value for opt.precision is 3; this corresponds to maximum observed error of 0.1%.

As a rule of thumb, increasing precision by 1 quadruples the number of operations needed to determine the length; exact numbers vary for every individual curve, however. Precision 3 is considered good enough when drawing curve approximations, and precision 4 is considered good enough for mapping curve t values to curve length. (Precision 4 should be the highest necessary for any practical use.)

The measure used, observed error (difference between subsequent observed lengths), is not a measure of actual error (difference between observed length and the actual length); it is a necessary substitution, however. The actual curve length cannot be precisely determined in the general case, and obtaining flattened length at maximum precision is not feasible for every single length calculation. Still, actual error is generally 2-3 times lower than observed error, so opt.precision can be seen as an upper bound on the length error with a high degree of confidence.

Instead of opt.precision, the opt.subdivisions property may be specified, directly providing an array of pre-computed curve subdivisions from which to calculate curve length. This is useful when several operations need to be performed with the same curve at the same level of precision (for example, obtaining the length of the curve and then finding the point at 10% length). Use the curve.getSubdivisions() function to obtain an array of curve subdivisions.

lengthAtT()

curve.lengthAtT(t [, opt])

Return the length of the curve up to the point specified by t.

The curve is divided at t and the length of the first subcurve is returned. For more information about curve length calculation refer to curve.length() documentation.

The default value for opt.precision is 3; this corresponds to maximum observed error of 0.1%.

This method does make use of the opt.subdivisions property.

pointAt()

curve.pointAt(ratio [, opt])

Return a point on the curve that lies ratio (normalized length) away from the beginning of the curve.

The function expects ratio to lie between 0 and 1; values outside the range are constrained to 0 and 1, respectively.

This function mirrors the functionality of the line.pointAt() function. If the point at a given t value is needed instead, use the curve.pointAtT() function.

The function uses the same algorithm as the curve.pointAtLength() function.

The default value for opt.precision is 3; this corresponds to maximum observed error of 0.1%.

The opt.subdivisions property may be specified, directly providing an array of pre-computed curve subdivisions from which to calculate curve length. Use the curve.getSubdivisions() function to obtain an array of curve subdivisions. The opt.precision property is still necessary, however; it determines the precision of the point search algorithm.

pointAtLength()

curve.pointAtLength(length [, opt])

Return a point on the curve that lies length away from the beginning of the curve.

If negative length is provided, the algorithm starts looking from the end of the curve. If length is higher than curve length, the closest curve endpoint is returned instead.

The curve is first subdivided, according to opt.precision (refer to curve.length() documentation for more information about precision and curve flattening). Then, one subdivision is identified which contains the point at length. A binary search is then performed on that subdivision, until a curve is found whose endpoint lies within opt.precision away from length. That endpoint is returned by the function.

The default value for opt.precision is 3; this corresponds to maximum observed error of 0.1%.

As a rule of thumb, increasing precision by 1 doubles the number of operations needed to find the point to be returned (this is on top of the cost of curve subdivision); exact numbers vary for every individual curve, however.

The opt.subdivisions property may be specified, directly providing an array of pre-computed curve subdivisions from which to calculate curve length. Use the curve.getSubdivisions() function to obtain an array of curve subdivisions. The opt.precision property is still necessary, however; it determines the precision of the point search algorithm.

pointAtT()

curve.pointAtT(t)

Return a point on the curve at a point specified by t.

The function expects t to lie between 0 and 1; values outside the range are constrained to 0 and 1, respectively.

This function is not a counterpart to the line.pointAt() function. The relationship between t and distance along a curve is complex and non-linear. If a point at a certain ratio (normalized length) away from beginning of the curve is needed, use the curve.pointAt() function.

round()

curve.round([precision])

Round all coordinates of the curve to the given precision.

Default precision is 0.

Modifies this curve in-place, and returns it.

scale()

curve.scale(sx, sy [, origin])

Scale the curve by sx and sy about the given origin.

If origin is not specified, the curve is scaled around 0,0.

tAt()

curve.tAt(ratio [, opt])

Return the t value of the point that lies ratio (normalized length) away from the beginning of the curve.

The function expects ratio to lie between 0 and 1; values outside the range are constrained to 0 and 1, respectively.

The function uses the same algorithm as the curve.tAtLength() function.

The default value for opt.precision is 3; this corresponds to maximum observed error of 0.1%.

The opt.subdivisions property may be specified, directly providing an array of pre-computed curve subdivisions from which to calculate curve length. Use the curve.getSubdivisions() function to obtain an array of curve subdivisions. The opt.precision property is still necessary, however; it determines the precision of the point search algorithm.

tAtLength()

curve.tAtLength(length [, opt])

Return the t value of the point that lies length away from the beginning of the curve.

If negative length is provided, the algorithm starts looking from the end of the curve. If length requested is higher than curve length, the t of the closest curve endpoint (0 or 1) is returned instead.

The curve is first subdivided, according to opt.precision (refer to curve.length() documentation for more information about precision and curve flattening). Then, one subdivision is identified which contains the point at length. A binary search is then performed on that subdivision, until a curve is found whose endpoint lies within opt.precision away from length. The t value of that endpoint is returned by the function.

The default value for opt.precision is 3; this corresponds to maximum observed error of 0.1%.

The opt.subdivisions property may be specified, directly providing an array of pre-computed curve subdivisions from which to calculate curve length. Use the curve.getSubdivisions() function to obtain an array of curve subdivisions. The opt.precision property is still necessary, however; it determines the precision of the point search algorithm.

tangentAt()

curve.tangentAt(ratio [, opt])

Return a line that is tangent to the curve at a point that lies ratio (normalized length) away from the beginning of the curve.

The function expects ratio to lie between 0 and 1; values outside the range are constrained to 0 and 1, respectively.

The tangent line starts at the specified point. The direction from start to end is the same as the direction of the curve at the specified point.

If the control points of the curve all lie at the same coordinates, null is returned (it is impossible to determine the slope of a point). The curve.isDifferentiable() function may be used in advance to determine whether tangents can exist for a given curve.

The function uses the same algorithm as the curve.tangentAtLength() function.

The default value for opt.precision is 3; this corresponds to maximum observed error of 0.1%.

The opt.subdivisions property may be specified, directly providing an array of pre-computed curve subdivisions from which to calculate curve length. Use the curve.getSubdivisions() function to obtain an array of curve subdivisions. The opt.precision property is still necessary, however; it determines the precision of the point search algorithm.

tangentAtLength()

curve.tangentAtLength(length [, opt])

Return a line that is tangent to the curve at a point that lies length away from the beginning of the curve.

If negative length is provided, the algorithm starts looking from the end of the curve. If length is higher than curve length, a line tangent to the closest curve endpoint is returned instead.

The tangent line starts at the specified point. The direction from start to end is the same as the direction of the curve at the specified point.

If the control points of the curve all lie at the same coordinates, null is returned (it is impossible to determine the slope of a point). The curve.isDifferentiable() function may be used in advance to determine whether tangents can exist for a given curve.

The curve is first subdivided, according to opt.precision (refer to curve.length() documentation for more information about precision and curve flattening). Then, one subdivision is identified which contains the point at length. A binary search is then performed on that subdivision, until a curve is found whose endpoint lies within opt.precision away from length. That endpoint is used as the start of the tangent line.

The default value for opt.precision is 3; this corresponds to maximum observed error of 0.1%.

The opt.subdivisions property may be specified, directly providing an array of pre-computed curve subdivisions from which to calculate curve length. Use the curve.getSubdivisions() function to obtain an array of curve subdivisions. The opt.precision property is still necessary, however; it determines the precision of the point search algorithm.

tangentAtT()

curve.tangentAtT(t)

Return a line that is tangent to the curve at point specified by t.

The function expects t to lie between 0 and 1; values outside the range are constrained to 0 and 1, respectively.

The tangent line starts at the specified point. The direction from start to end is the same as the direction of the curve at the specified point.

If the control points of the curve all lie at the same coordinates, null is returned (it is impossible to determine the slope of a point). The curve.isDifferentiable() function may be used in advance to determine whether tangents can exist for a given curve.

toPoints()

curve.toPoints([opt])

Return an array of points that approximate the curve at given precision.

The points obtained are endpoints of curve subdivisions whose flattened length is up to the specified precision level away from actual curve length. Refer to curve.length() documentation for more information about precision and curve flattening.

The default value for opt.precision is 3; this corresponds to maximum observed error of 0.1% in flattened curve length.

Instead of opt.precision, the opt.subdivisions property may be specified, directly providing an array of pre-computed curve subdivisions from which to obtain the array of points. Use the curve.getSubdivisions() function to obtain an array of curve subdivisions.

toPolyline()

curve.toPolyline([opt])

Return a polyline that approximates the curve at given precision.

The polyline points are found as endpoints of curve subdivisions whose flattened length is up to the specified precision level away from actual curve length. Refer to curve.length() documentation for more information about precision and curve flattening.

The default value for opt.precision is 3; this corresponds to maximum observed error of 0.1% in flattened curve length.

Instead of opt.precision, the opt.subdivisions property may be specified, directly providing an array of pre-computed curve subdivisions from which to obtain the polyline. Use the curve.getSubdivisions() function to obtain an array of curve subdivisions.

toString()

curve.toString()

Return the curve represented as a string.

new g.Curve('10 10', '10 20', '20 20', '20 10').toString() = "10@10 10@20 20@20 20@10"

translate()

curve.translate(tx [, ty])

Translate the curve by tx on the x-axis and by ty on the y-axis.

If only tx is specified and is a number, ty is considered to be zero. If only tx is specified and is an object, it is considered to be a point or an object in the form { x: [number], y: [number] }

Static methods

throughPoints()

g.Curve.throughPoints(points)

Return an array of cuic bezier curves that defines a curve passing through provided points.

This method automatically computes the cubic bezier control points necessary to create a smooth curve with points as intermediary endpoints. An error is thrown if an array with fewer than two points is provided.

The result of this function may be provided directly to the g.Path() constructor in order to create a Path object from these curves.