This is Words and Buttons Online — a collection of interactive #tutorials, #demos, and #quizzes about #mathematics, #algorithms and #programming.

The simplest possible smooth contouring algorithm

Contouring algorithm is something that turns your implicit function into a contour. Marching cubes and dual method are the most noted examples.

There is also a simpler algorithm. It may be not as efficient computationally, but due to it's simplicity, it can be easily improved to produce smooth contours and not just polylines. Here's an interactive plot to show how it works.


The algorithm accepts a distance function for input. This function denotes the distance to the expected curve for every point on the plane.

The first phase of the algorithm is finding the initial contour. Let's iterate through all the cells of a grid. If the distance function changes its sing between the neighboring cells' centers, we'll add a piece of contour between them. We have to put one horizontal and one vertical piece per cube to form a fully closed contour.

The second phase is attracting the contour nodes to the expected curve. The distance function shows how far every node is from the expected curve. And the direction to shift our node is also detectable from the distance function's gradient.

All we have to do is to add a gradient vector multiplied by an inverse distance to every node point.

The third phase is adding curvature. Once again, we'll measure the function's gradient for every node. We'll use the partial derivatives from it to form a parametric 3-rd degree polynomial.

It probably sounds more complicated than it is. The 3-rd degree polynomials for x and y are the solutions for these systems:

axt03 + bxt02 + cxt0 + dx = x0
3axt02 + 2bxt0 + cx = dx0 / dt0
axt13 + bxt12 + cxt1 + dx = x1
3axt12 + 2bxt1 + cx = dx1 / dt1

axt03 + bxt02 + cxt0 + dx = y0
3axt02 + 2bxt0 + cx = dy0 / dt0
axt13 + bxt12 + cxt1 + dx = y1
3axt12 + 2bxt1 + cx = dy1 / dt1

If you parametrize the polynomials for t = [0..1], the systems will become:

dx = x0
cx = dx0 / dt0
ax + bx + cx + dx = x1
3ax + 2bx + cx = dx1 / dt1

dx = y0
cx = dy0 / dt0
ax + bx + cx + dx = y1
3ax + 2bx + cx = dy1 / dt1

The concepts on which the algorithm is built may not be simple: partial derivatives, gradients, parametric polynomials. But the algorithm itself is: cells → lines → curves.