Curves.Spline.Type.BezierSpline (curves v1.0.1)

Copy Markdown View Source

A chain of Bezier curves, each one starting where the last one ended.

Each point is a list: a knot, then the control points of the curve from that knot to the next one, just like the commands in an SVG path (or bezierCurveTo on a canvas):

PointCurve to the next knotSVG
[knot]a straight lineL
[knot, c]a quadratic curve pulled towards cQ
[knot, c0, c1]a cubic curve: leaves knot towards c0, arrives at the next knot from c1C
[knot, {:arc, rx, ry, rotation, large_arc, sweep}]an elliptical arcA

The last point only ends the curve, so it must be [knot].

Arcs

An arc goes from its knot to the next knot along an ellipse with radii rx and ry, whose x axis is tilted by rotation degrees, exactly like SVG's A rx ry rotation large-arc-flag sweep-flag x y (with true and false for SVG's 1 and 0). There are usually four such arcs between two points, and the flags pick one:

  • large_arc - true takes the long way round (more than half the ellipse), false the short way.
  • sweep - true makes the angle go up: anticlockwise in Curves' pictures, where y goes up, and clockwise on an SVG screen, where y goes down. false goes the other way.
sweep: falsesweep: true
large_arc: falseShort way, angle going downShort way, angle going up
large_arc: trueLong way, angle going downLong way, angle going up

Also like SVG: radii too small to reach the next knot are scaled up until they just do, a radius of 0 draws a straight line, negative radii count as positive, and an arc to a knot in the same place draws nothing (the segment stays on that point). An arc is exact (it is not made of Bezier curves), starts and ends exactly on its knots, and moves through its angle at a steady rate.

The curve stores some extra points for each arc, between its knots: the arc is cut into pieces of at most a quarter turn, and each piece adds the point where the tangents at its ends meet (and its end). The arc never goes outside them, so :force_percent stays within 0.0..1.0, and Curves.Svg draws them as dots with dashed lines, like a quadratic curve's control point.

points = [
  # Each point: a knot, then the control points of the curve to the next knot.
  [{5.0, 10.0}, {10.0, 10.0}, {5.0, 5.0}],    # cubic to {10, 5}   (SVG C)
  [{10.0, 5.0}, {15.0, 5.0}, {15.0, 6.0}],    # cubic to {15, 10}
  [{15.0, 10.0}, {15.0, 14.0}, {18.0, 15.0}], # cubic to {20, 15}
  [{20.0, 15.0}, {23.0, 15.0}, {32.0, 5.0}],  # cubic to {30, 10}
  [{30.0, 10.0}]                              # the last knot only ends the curve
]
curve = Curves.define_bezier_spline(points)

# Find any point along the curve (u goes from 0.0 to Curves.max_u(curve))...
Curves.solve!(curve, 1.5)

# ...or draw the whole curve as an SVG image
Curves.Svg.save!(curve, "bezier_spline.svg")

Bezier Spline