Handling Bezier Paths (Splines)

class beziers.path.BezierPath

Bases: beziers.utils.booleanoperationsmixin.BooleanOperationsMixin, beziers.utils.samplemixin.SampleMixin, object

BezierPath represents a collection of Segment objects - the curves and lines that make up a path.

One of the really fiddly things about manipulating Bezier paths in a computer is that there are various ways to represent them. Different applications prefer different representations. For instance, when you’re drawing a path on a canvas, you often want a list of nodes like so:

{ "x":255.0, "y":20.0, "type":"curve"},
{ "x":385.0, "y":20.0, "type":"offcurve"},
{ "x":526.0, "y":79.0, "type":"offcurve"},
{ "x":566.0, "y":135.0, "type":"curve"},
{ "x":585.0, "y":162.0, "type":"offcurve"},
{ "x":566.0, "y":260.0, "type":"offcurve"},
{ "x":484.0, "y":281.0, "type":"curve"},
...

But when you’re doing Clever Bezier Mathematics, you generally want a list of segments instead:

[ (255.0,20.0), (385.0,20.0), (526.0,79.0), (566.0,135.0)],
[ (566.0,135.0), (585.0,162.0), (566.0,260.0), (484.0,281.0)],

The Beziers module is designed to allow you to move fluidly between these different representations depending on what you’re wanting to do.

classmethod fromPoints(points, error=50.0, cornerTolerance=20.0, maxSegments=20)
Fit a poly-bezier curve to the points given. This operation should be familiar

from ‘pencil’ tools in a vector drawing application: the application samples points where your mouse pointer has been dragged, and then turns the sketch into a Bezier path. The goodness of fit can be controlled by tuning the error parameter. Corner detection can be controlled with cornerTolerance.

Here are some points fit with error=100.0:

curvefit1

And with error=10.0:

curvefit1
classmethod fromSegments(array)

Construct a path from an array of Segment objects.

classmethod fromNodelist(array, closed=True)

Construct a path from an array of Node objects.

classmethod fromGlyphsLayer(layer)

Returns an array of BezierPaths from a Glyphs GSLayer object.

classmethod fromFonttoolsGlyph(font, glyphname)

Returns an array of BezierPaths from a FontTools font object and glyph name.

asSegments()

Return the path as an array of segments (either Line, CubicBezier, or, if you are exceptionally unlucky, QuadraticBezier objects).

asNodelist()

Return the path as an array of Node objects.

asSVGPath()

Return the path as a string suitable for a SVG <path d=”…”? element.

asMatplot()
plot(ax, **kwargs)

Plot the path on a Matplot subplot which you supply

import matplotlib.pyplot as plt
fig, ax = plt.subplots()
path.plot(ax)
clone()

Return a new path which is an exact copy of this one

round()

Rounds the points of this path to integer coordinates.

bounds()

Determine the bounding box of the path, returned as a BoundingBox object.

splitAtPoints(splitlist)
addExtremes()

Add extreme points to the path.

property length

Returns the length of the whole path.

pointAtTime(t)

Returns the point at time t (0->1) along the curve, where 1 is the end of the whole curve.

lengthAtTime(t)

Returns the length of the subset of the path from the start up to the point t (0->1), where 1 is the end of the whole curve.

offset(vector, rotateVector=True)
Returns a new BezierPath which approximates offsetting the

current Bezier path by the given vector. Note that the vector will be rotated around the normal of the curve so that the offsetting always happens on the same ‘side’ of the curve:

offset1

If you don’t want that and you want ‘straight’ offsetting instead (which may intersect with the original curve), pass rotateVector=False:

offset1
append(other, joinType='line')

Append another path to this one. If the end point of the first path is not the same as the start point of the other path, a line will be drawn between them.

reverse()

Reverse this path (mutates path).

translate(vector)

Translates the path by a given vector.

rotate(about, angle)

Rotate the path by a given vector.

scale(by)

Scales the path by a given magnitude.

balance()

Performs Tunni balancing on the path.

findDiscontinuities()

Not implemented yet

roundCorners()

Not implemented yet

dash(lineLength=50, gapLength=None)
Returns a list of BezierPath objects created by chopping

this path into a dashed line:

paths = path.dash(lineLength = 20, gapLength = 50)
path.dash(lineLength = 20, gapLength = 50)
segpairs()
harmonize(seg1, seg2)
flatten(degree=8)
windingNumberOfPoint(pt)
pointIsInside(pt)

Returns true if the given point lies on the “inside” of the path, assuming an ‘even-odd’ winding rule where self-intersections are considered outside.

property area

Approximates the area under a closed path by flattening and treating as a polygon.

property centroid
drawWithBrush(other)

Assuming that other is a closed Bezier path representing a pen or brush of a certain shape and that self is an open path, this method traces the brush along the path, returning an array of Bezier paths.

other may also be a function which, given a time t (0-1), returns a closed path representing the shape of the brush at the given time.

This requires the shapely library to be installed.

quadraticsToCubics()

Converts all quadratic segments in the path to cubic Beziers.

thicknessAtX(x)

Returns the thickness of the path at x-coordinate x.

distanceToPath(other, samples=10)

Finds the distance to the other curve at its closest point, along with the t values for the closest point at each segment and the relevant segments.

Returns: distance, t1, t2, seg1, seg2.

tidy(**kwargs)

Tidies a curve by adding extremes, and then running removeIrrelevantSegments and smooth. relLength, absLength, maxCollectionSize, lengthLimit and cornerTolerance parameters are passed to the relevant routine.

removeIrrelevantSegments(relLength=2e-05, absLength=0)

Removes small and collinear line segments. Collinear line segments are adjacent line segments which are heading in the same direction, and hence can be collapsed into a single segment. Small segments (those less than absLength units, or less than relLength as a fraction of the path’s total length) are removed entirely.

smooth(maxCollectionSize=30, lengthLimit=20, cornerTolerance=10)

Smooths a curve, by collating lists of small (at most lengthLimit units long) segments at most maxCollectionSize segments at a time, and running them through a curve fitting algorithm. The list collation also stops when one segment turns more than cornerTolerance degrees away from the previous one, so that corners are not smoothed.