Next: , Previous: Drawing commands, Up: Top


5 Bezier curves

Each interior node of a cubic spline may be given a direction prefix or suffix {dir}: the direction of the pair dir specifies the direction of the incoming or outgoing tangent, respectively, to the curve at that node. Exterior nodes may be given direction specifiers only on their interior side.

A cubic spline between the node z_0, with postcontrol point c_0, and the node z_1, with precontrol point c_1, is computed as the Bezier curve


(1-t)^3*z_0+3t(1-t)^2*c_0+3t^2(1-t)*c_1+t^3*z_1 for 0 <=t <= 1.

As illustrated in the diagram below, the third-order midpoint (m_5) constructed from two endpoints z_0 and z_1 and two control points c_0 and c_1, is the point corresponding to t=1/2 on the Bezier curve formed by the quadruple (z_0, c_0, c_1, z_1). This allows one to recursively construct the desired curve, by using the newly extracted third-order midpoint as an endpoint and the respective second- and first-order midpoints as control points:


bezier2.png

Here m_0, m_1 and m_2 are the first-order midpoints, m_3 and m_4 are the second-order midpoints, and m_5 is the third-order midpoint. The curve is then constructed by recursively applying the algorithm to (z_0, m_0, m_3, m_5) and (m_5, m_4, m_2, z_1).

In fact, an analogous property holds for points located at any fraction t in [0,1] of each segment, not just for midpoints (t=1/2).

The Bezier curve constructed in this manner has the following properties:

The user can specify explicit control points between two nodes like this:

draw((0,0)..controls (0,100) and (100,100)..(100,0));

However, it is usually more convenient to just use the .. operator, which tells Asymptote to choose its own control points using the algorithms described in Donald Knuth's monograph, The MetaFontbook, Chapter 14. The user can still customize the guide (or path) by specifying direction, tension, and curl values.

The higher the tension, the straighter the curve is, and the more it approximates a straight line. One can change the spline tension from its default value of 1 to any real value greater than or equal to 0.75 (cf. John D. Hobby, Discrete and Computational Geometry 1, 1986):

draw((100,0)..tension 2 ..(100,100)..(0,100));
draw((100,0)..tension 3 and 2 ..(100,100)..(0,100));
draw((100,0)..tension atleast 2 ..(100,100)..(0,100));

In these examples there is a space between 2 and ... This is needed as 2. is interpreted as a numerical constant.

The curl parameter specifies the curvature at the endpoints of a path (0 means straight; the default value of 1 means approximately circular):

draw((100,0){curl 0}..(100,100)..{curl 0}(0,100));

The MetaPost ... path connector, which requests, when possible, an inflection-free curve confined to a triangle defined by the endpoints and directions, is implemented in Asymptote as the convenient abbreviation :: for ..tension atleast 1 .. (the ellipsis ... is used in Asymptote to indicate a variable number of arguments; see Rest arguments). For example, compare

draw((0,0){up}..(100,25){right}..(200,0){down});

dots.png

with

draw((0,0){up}::(100,25){right}::(200,0){down});

colons.png

The --- connector is an abbreviation for ..tension atleast infinity.. and the & connector concatenates two paths, after first stripping off the last node of the first path (which normally should coincide with the first node of the second path).