Bezier Curves

You can draw quadratic Bezier curves with the command Q(l,lc,ac). The variable l is the straight line distance, in the current direction, to the point the curve will connect to. The variable lc is the distance to the control point which is at an angle ac with respect to the current direction. For positive ac this is counterclockwise from the current direction and for negative ac it is clockwise. If you draw lines from the curve start and end points to the control point then the curve will start and end tangent to those lines.

The program (bezier1.nll) draws a quadratic Bezier curve between two points and it draws lines from the start and end of the curve to the control point so you can see how the curve is tangent to the lines. The command Q(1,1.5,ac) indicates that the straight line distance between the start and end points is 1. The distance of the control point from the start point is 1.5 and the direction of the control point is ac which is set to pi/6.

Program: (bezier1.nll)

l = 1;
lc = 1.5;
ac = pi/6;
lp = sqrt(l^2+lc^2-2*l*lc*cos(ac));
ap = pi-asin(lc*sin(ac)/lp);
START : P(0.1,0.1) T(pi/6) [T(ac) L(lc) T(-ac-ap) L(lp)] Q(1,1.5,ac);

Command line

nell bezier1.nll START 3 | nellsvg 1.25 1.5 in 0.015 1 > bezier1.svg

One of the nice things you can do with a Bezier curve is draw an exact parabola. Program (bezier2.nll) draws four parabolas between the same two points separated by distance l=2. The parabolas are of the form y=ax^2 for a=2, 1, 1/2, 1/4.

Program: (bezier2.nll)

a = 2;
l = 2;
P1 : [Q(l,(l/2)*sqrt(a^2*l^2+1),atan(-a*l))] A(a,a/2);
START : P(0,2) S(P1,4);

Command line

nell bezier2.nll START 3 | nellsvg 2 2 in 0.015 1 > bezier2.svg

Using parabolas you can create a very close approximation to a sine function. Program (bezier3.nll) draws an approximation of three periods of a sine function. Each half period is actually a parabola. The same control point distance is used for each parabola but the control point angles alternate in sign.

Program: (bezier3.nll)

a = 4;
l = 1;
lc = (l/2)*sqrt(a^2*l^2+1);
ac = atan(-a*l);
P1 : Q(l,lc,-ac) Q(l,lc,ac);
START : P(0,1) S(P1,3);

Command line

nell bezier3.nll START 3 | nellsvg 6 2 in 0.02 1 > bezier3.svg

The program (bezier4.nll) draws a heart shaped object. You can experiment with different shapes by changing the values of lc and ac.

Program: (bezier4.nll)

lc = 3;
ac = pi/5;
START : M(1) T(pi/2) [Q(1,lc,ac)] Q(1,lc,-ac);

Command line

nell bezier4.nll START 3 | nellsvg 2 2 in 0.02 1 > bezier4.svg

The program (bezier5.nll) draws a flower like object.

Program: (bezier5.nll)

T1 : [Q(1,2,pi/10) M(0.25) C(0.1)] [Q(1,2,-pi/10)];
T2 : S(T1,1) T(pi/5);
START : P(1.4,1.4) S(T2,10);

Command line

nell bezier5.nll START 3 | nellsvg 2.8 2.8 in 0.02 1 > bezier5.svg

The program (clover.nll) draws a four leaf clover.

Program: (clover.nll)

l = 1;
lc = 1.75;
ac = 0.22*pi;
as = -3*pi/4+ac/2; stem angle
das = 0.02; controls stem width
LEAF : [Q(l,lc,ac)] [Q(l,lc,-ac)];
T1 : S(LEAF,1) T(pi/2);
STEM : [T(as-das) Q(2,1.5,-pi/8)] T(as+das) Q(2,1.5,-pi/8);
START : P(1.25,1.75) T(pi/3) S(T1,4) S(STEM,1);

Command line

nell clover.nll START 3 | nellsvg 2.6 3 in 0.02 1 > clover.svg

You can draw cubic Bezier curves with the command B(l,lc1,ac1,lc2,ac2). The command is very similar to the quadratic Bezier command but with one extra control point whose distance and direction are with respect to the end point of the curve. The extra control point allows more complicated curves to be drawn. As in the quadratic curve, the variable l is the straight line distance, in the current direction, to the point the curve will connect to. lc1 and ac1 are the distance and direction of the first control point with respect to the start of the curve while lc2 and ac2 are the distance and direction of the second control point with respect to the end of the curve. If you draw lines from the start of the curve to the first control point and from the end of the curve to the second control point then the curve will be tangent to those lines at the start and end.

The program (bezier6.nll) draws a cubic Bezier curve between two points and it draws lines from the start and end of the curve to the control points so you can see how the curve is tangent to the lines. The straight line distance between the start and end points is 1. The distance to both control points is 2 but note that for the second control point the distance is negative which has the effect of flipping the direction 180 degrees or pi radians.

Program: (bezier6.nll)

l = 1;
lc1 = 2;
ac1 = pi/6;
lc2 = -2;
ac2 = pi/6;
START : P(0.5,1) [T(ac1) L(lc1)] B(l,lc1,ac1,lc2,ac2) [T(ac2) L(lc2)];

Command line

nell bezier6.nll START 3 | nellsvg 2 2 in 0.02 1 > bezier6.svg

The program (bezier7.nll) is basically the same as (bezier6.nll) but with the sign on ac2 negative. This has a dramatic effect on the shape of the curve.

Program: (bezier7.nll)

l = 1;
lc1 = 2;
ac1 = pi/6;
lc2 = -2;
ac2 = -pi/6;
START : P(0.5,1) [T(ac1) L(lc1)] B(l,lc1,ac1,lc2,ac2) [T(ac2) L(lc2)];

Command line

nell bezier7.nll START 3 | nellsvg 2 2 in 0.02 1 > bezier7.svg

The program (bezier8.nll) draws a Bezier curve between the vertices of an n-sided polygon.

Program: (bezier8.nll)

n = 7;
a = 2*pi/n;
l = 1;
lc1 = 2;
ac1 = pi/6;
lc2 = -2;
ac2 = -pi/6;
T1 : B(l,lc1,ac1,lc2,ac2) T(a);
START : P(0.75,0) S(T1,n);

Command line

nell bezier8.nll START 3 | nellsvg 2.5 2.25 in 0.02 1 > bezier8.svg

The program (bezier9.nll) is the same as (bezier8.nll) but with different parameter values.

Program: (bezier9.nll)

n = 4;
a = 2*pi/n;
l = 2;
lc1 = 4;
ac1 = pi/6;
lc2 = -4;
ac2 = -pi/6;
T1 : B(l,lc1,ac1,lc2,ac2) T(a);
START : S(T1,n);

Command line

nell bezier9.nll START 3 | nellsvg 2 2 in 0.02 1 > bezier9.svg