On this page:
6.5.1 Exercises 31
6.5.1.1 Question 103
6.5.1.2 Question 104

6.5 Polygonal Lines and Splines

We have seen that arrays allow the storage of a variable number of elements, and we have also seen that is possible to use arrays to separate the programs that create the vertices of a geometric shape from the programs that use those vertices to create the graphical representation of that shape.

In the case of the polygon function discussed in the section Polygons, the arrays of vertices are used to create polygons, i.e., planar shapes delimited by a closed path. In other cases, however, we want to create shapes that are not delimited by closed paths, or where the paths are not sequences of line segments, or that are not even planar. To address these cases, we need to use functions which, given arrays of positions, create other types of geometric shapes.

The simplest case is a polygonal line, not necessarily planar. If it is open, we use the line function and, if it is closed, we use the polygon function. Both functions accept a variable number of arguments corresponding to the vertices of the polygonal line or an array containing these vertices.

If, instead of a polygonal line, we want a smooth curve passing through a sequence of positions, we use the spline function when the curve is open and the closed_spline function when the curve is closed. As the line and polygon functions, these also accept a variable number of positions or an array with these positions.

The difference between a polygonal line and a spline is visible in this figure: it compares the same sequence of points linked with a polygonal line and with a spline. The image was produced by evaluating the following expressions:

points = [xy(0, 2),

          xy(1, 4),

          xy(2, 0),

          xy(3, 3),

          xy(4, 0),

          xy(5, 4),

          xy(6, 0),

          xy(7, 2),

          xy(8, 1),

          xy(9, 4)]

line(points)

spline(points)

Comparison between a polygonal line and a spline, connecting the same set of points.

image

Naturally, the manual specification of point coordinates is rather inconvenient, being therefore preferable to automatically compute them according to the mathematical definition of the desired curve. For example, imagine we intend to draw a sinusoid curve starting at a point \(P\). Unfortunately, the list of geometrical figures provided by Khepri (points, lines, rectangles, polygons, circles, arcs, etc.) does not include the sinusoid. Fortunately, we can create an approximation to a sinusoid curve by computing a sequence of points belonging to the sinusoid curve and join them using a polygonal line or, even better, using a spline curve.

To compute the set of values of the sine function in the interval \([x_0, x_1]\), we need to consider an increment \(\Delta_x\) so that, starting at the point \(x_0\) and going from the point \(x_i\) to the point \(x_ {i +1}\) using \(x_{i+1}=x_i+\Delta_x\), we successively calculate the value of \(\sin(x_i)\) until \(x_i\) exceeds \(x_1\). To create a recursive definition for this problem we can assume that, when \(x_0>x_1\), the result is an empty array of coordinates. Otherwise, we add the coordinate \((x_0,\sin(x_0))\) to the array of sine coordinates for the interval \([x_0+\Delta_x, x_1]\). This process is implemented by the following function:

sine_points(x0, x1, dx) =

  if x0 > x1

    []

  else

    [xy(x0, sin(x0)), sine_points(x0+dx, x1, dx)...]

  end

To have greater freedom in the positioning of the sinusoid curve in space, we add to the previous function a point \(P\) in relation to which the curve is positioned:

sine_points(p, x0, x1, dx) =

  if x0 > x1

    []

  else

    [p+vy(sin(x0)), sine_points(p+vx(dx), x0+dx, x1, dx)...]

  end

The curves resulting from the evaluation of the following expressions are shown in this figure, in which the points are joined through polygonal lines:

line(sine_points(xy(0.0, 1.0), 0.0, 6.0, 1.0))

line(sine_points(xy(0.0, 0.5), 0.0, 6.5, 0.5))

line(sine_points(xy(0.0, 0.0), 0.0, 6.4, 0.2))

Sinusoid curves drawn using polygonal lines with an increasing number of points (from top to bottom).

image

Note that, in this figure, we vertically separated the curves to better understand the different degrees of accuracy we can have. It is plainly evident that, the more points are used, the smoother the polygonal line becomes. However, we must also consider that the greater the number of points used, the greater is the computational effort made by Khepri and by the CAD tool being used.

To obtain an even better approximation, although at the cost of a greater computational effort, we can use the spline function instead of the line function. The result is presented in this figure.

Sinusoid curves drawn using splines with an increasing number of points (from top to bottom).

image

6.5.1 Exercises 31
6.5.1.1 Question 103

Define the sinusoid_circular_points function that, given the parameters \(P\), \(r_i\), \(r_o\), \(c\), and \(n\), computes \(n\) points of a closed curve in the shape of a sinusoid with \(c\) cycles, developed along a circular ring centered at the point \(P\) and enclosed by the inner radius \(r_i\) and outer radius \(r_o\). The outcome of this function can be seen in the various examples presented in the following figure in which, from left to right, the number of \(c\) cycles is 12, 6 and 3.

image

6.5.1.2 Question 104

Define the random_circle_points function, with parameters \(P\), \(r_0\), \(r_1\), and \(n\), which computes \(n\) points of a closed random curve developed along a circle centered at the point \(P\) and enclosed by the inner radius \(r_0\) and outer radius \(r_1\). The outcome of this function can be seen in the various examples presented in the following figure in which, from left to right, the number of points gradually increase, thereby increasing the curve’s irregularity.

image

Suggestion: for computing the points, consider using polar coordinates to evenly distribute the points around a circle but with the distance to the center varying randomly between \(r_0\) and \(r_1\). For example, consider that the leftmost curve in the figure was generated by the following expression:

closed_spline(random_circle_points(xy(0, 0), 1, 2, 4))