Lesson 1 introduced a number of 2d primitives, namely: arcs, ellipses, lines, points, quads, rectangles, and triangles. However, many shapes do not fit into any such category – like hearts (♥), stars (★), octagons, and Pikachu silhouettes, to name just a few. In this tutorial, you’ll look at drawing with points and curves, as opposed to more restrictive shape functions. Fonts also rely on curves to describe each glyph, and the latter part of this tutorial delves into Typography (and by extension, strings). Be forewarned: lesson 2 may be a little tedious, but is necessary to lay down important programming and drawing fundamentals for future lessons.
Processing deals with two types of curves: Bézier and Catmull-Rom. Both are named after the people who developed them, and both involve some complicated math. Fortunately, the complex underlying calculus is handled by Processing’s various curve functions, leaving you to deal with just the coordinates of a few control points.
The best way to grasp curves is to draw a few, then manipulate their control points. Create a new sketch and save it as “curves”. This section will be coordinate-intensive; so, to make things easier, download this “grid.png” file:
Additional sketch assets (images, fonts, and other media) always belong in a sub-folder named “data”. Create a new data folder within your curves sketch now and place the grid.png within it:
Frustratingly, many operating systems hide file extensions – that’s, the
.png part of the file. However, if you dig around in your Windows or Mac Finder settings, you can get extensions to show in your file manager.
This grid will lie beneath everything you draw, assisting you in gauging x/y-coordinates. Setup your sketch using the following code:
Note that it’s essential to include the file extension (
'grid.png') when referencing the image file.
curve() function is an implementation of Catmull-Rom splines (named after Edwin Catmull and Raphael Rom). Once visualised, the operation of these curves is intuitive.
Add a diagonal line to your “curves” sketch:
A line is drawn between the pairs of x/y coordinates specified, corresponding to the relevant lines on the grid. Now comment out the
line() function and replace it with a
The visual result is exactly the same. If you study the
curve() arguments, you’ll notice that the four middle values match those of the
curve(0,0, 100,100, 400,400, 500,500)
500,500 arguments represent the control point coordinates, but more on those shortly. Set the stroke to yellow and add another
In this instance, the control point coordinates have been tweaked – resulting in a yellow curve with a slight S-bend:
Now for the part where it all makes sense! To provide a clearer idea of how the control points work, add the following code:
With the control point curves visualised, it should be evident how these determine the direction and amount of curvature. If you’ve ever used a flexible curve, this will look familiar. If you’re interested to know how smooth curves were ever drawn without computers, then look these up.
curveTightness() function determines how the curve fits, as if you were replacing it with a less/more elastic material. The function accepts values ranging from
0 being the default. To experiment, add a
curveTightness() line above the
stroke('#FFFF00'), so as to affect all of the curves beneath it.
French engineer, Pierre Bézier popularised, but did not create the Bézier curve. He used them in his of design automobile bodies at Renault, devising a system whereby the shape of a curve is controlled by series of anchor and control points. If you’ve any experience with vector graphics drawing software, these will look familiar. Popular such applications include Adobe Illustrator and Inkscape, where Bézier curves are commonly referred to as “paths”.
Bézier curves are widely used in computer graphics. Their ability to model smooth curves makes them fundamental to vector graphics, animation paths, and fonts. Vector graphics (such as SVG files) can scale to any size – making them resolution-independent. Consider a digital photograph: as you zoom further and further in toward a given point, discernible squares of colour appear. Popular photographic file formats, such as JPG and PNG, are comprised of a pixel grid, the dimensions of which limit the overall resolution. However, in the case of vector-based graphics, the points along a Bézier curve can be recalculated to fit any resolution.
bezier() function takes the following arguments, expanded across multiple lines here for easier comprehension:
Yikes! That’s a lot of arguments. Add some code to draw a Bézier curve, but use four variables to represent the control points:
Notice how all of the
cp__ variables reference the centre of the display window (
250, 250), meaning that all of the control points currently lie where the yellow and pale pink lines cross. To visualise how the curve is manipulated, add a red line connecting the first vertex and control point. Adjust the
cp1y variable to add some curve:
line() functions now share the control point’s x/y-coordinates. Making any adjustments to
cp1x, therefore, affects both functions. Add another red line to connect the lower/second vertex and control point:
Observe how the red handles ‘magnetically’ draw the line toward the control point. Getting the hang of where to place the vertex- and control points for any desired curve takes some practice. Perhaps try the Bézier Game to hone your skills:
You can also develop your Bézier skills using Inkscape (free), Illustrator, or other similar vector graphics drawing software. It’s usually easier to draw shapes using such software, then gauge the relevant control points for Processing – which is how the tasks for this tutorial were devised ;)