I became interested in Celtic knots after viewing a video showing how to draw them by hand. The technique begins with dots laid out on a square grid. Barriers are then added to the grid which form the outer border of the knot, as well as internal deflections.
I wanted to have a better way to generate these Celtic Knot illustrations, so I wrote a series of computer programs for generating them. My first attempt took advantage of a tile-based decomposition to create knots from smaller composite images. My more recent attempts have been with the HTML5 canvas element for dynamically generated images. The illustrations on this page were created with this program; you can try it yourself here.
There are several stylistic choices that can alter the appearance of the knot, such as how thick the strand is, whether the corners are rounded or sharp, and the smoothness of the turns of the strand. Shown here are knots generated by my programs with different choices of smoothness of the curvature of the strand, different strand widths, and different outline widths.
My first programming attempt made use of the fact that celtic knots of this style can be decomposed into a set of 35 base tiles, or just twelve tile types with rotations: By adjoining these images together with certain restrictions, a seamless Celtic knot image can be formed:
An alternative formulation is based on a decomposition into 'diamond' rather than square tiles. Diamonds overlap one fourth of two adjacent tiles and are a more natural means of expressing the composition of Celtic knots due to there being fewer distinct diamond types and simpler restrictions regarding their placement.
There are three diamond types: open, and horizontally- and vertically-closed. Within every diamond, strands enter and exit from the four sides. Inside the diamond, the strands may cross or deflect off of one another. Crossings occur only within open diamonds, and all internal deflections within the knot are due to horizontal or vertical closed diamonds.
One major shortcoming of the diamond decomposition becomes apparent when drawing or programming the generation of Celtic knot graphics. Diamonds do not visually align well under all combinations because the curvature of crossing and non-crossing strands exiting a diamond generally do not align well.
Celtic knots are interesting for a variety of reasons. One aspect I am trying to better understand is how the number of distinct strands in the knot is determined by the placement of internal barriers, or 'gates'. Some knots are composed of a single strand, while others can be composed of many different strands. The number of gates does not necessarily indicate anything about the number of strands in the knot; the addition of gates can increase, decrease, or not change the number of strands in the knot. To study these properties and for the purposes of generating computer graphics, it is useful to model Celtic knots through the use of graphs.
The edges in the knot graph are not placed simply based on visual appearance; strict rules exist for governing which vertices should be connected. Again visualizing the layout of diamonds discussed in the drawing section, we see that each diamond determines two connections between four vertices. If the diamond is 'open', then opposite vertices are connected; if it is horizontally or vertically closed, then the horizontal or vertical pairs are connected, respectively.
Dropping the checkerboard distinction between diamonds and instead focusing on their closure type provides an alternative way of visualizing the knot structure. The diamond graph or gate graph is a separate graph from the knot graph that can be formed by taking each diamond in the graph as a vertex, and adding edges between adjacent diamonds. The vertices of this graph can be colored according to the closure type of the diamond.
Celtic knots thus involve two types of graphs: the knot graph and the gate graph. The knot graph is always a 2-regular collection of cycles, and its structure is dictated by the coloring of the gate graph.
Drawing Celtic knots is somewhat difficult due to the self-overlapping and complex nature of the path of the strands. My strategy for generating computer graphics for these knots relies on the tile and subtile subdivision. The path of the strand enters and exists each subtile exactly once, aside from overlap due to drawing the strand with non-zero width.
The path that the strand follows within each subtile is essentially limited to three shapes: corners, diagonal, or straight-to-diagonal; however due to rotations and reflections, there are many paths under a fixed orientation. Rather than compositing arc segments and lines to create these curved paths, I make use of use Bezier curves. Bezier curves are parametrically-defined functions whose shape is determined by a number of control points. Coding separate cases for all of the path shapes would be tedious; with Bezier curves the control points can be selected based on the entering and exiting directions of the strand, and these control points can be selected independently.
While computer drawing of Celtic knots is more easily accomplished in terms of the "tile" decomposition, the essential structure of the knots is more easily generalized in terms of the "diamond" decomposition. This can be seen in my knot editing program, in which the user interface for manipulating the strands is based on the diamonds -- a diamond may be clicked to add or remove gates -- but the drawing routine is as described above, and is based on tiles.The general outline of the process is:
- Begin with a "premesh" graph, which defines the boundary of the knot and its interior structure.
- Use the premesh graph to induce a "Celtic mesh" graph. The faces of this graph are the diamonds within which the knot is drawn.
- Follow the same rules for drawing a Celtic knot by filling in the diamonds.
- Construction of the Celtic mesh graph is non-trivial; most graphs would not satisfy the requirements.
- The premesh graph determines the outer border of the knot and some of its key features.
- Every valid Celtic mesh graph can be induced from a premesh graph, and so requiring that we start from the premesh graph does not diminish the possible configurations we may end up with.
- Add a node for each node of the premesh graph.
- Add a node for each face of the premesh graph.
- For each interior edge in the premesh graph, add a four-sided face that connects its two incident nodes and the two nodes corresponding to its incident faces.
- For exterior edges, follow the same procedure but append a new node for the 'exterior face' (a new node for each exterior edge).
This procedure generalizes well and allows for many new knot configurations beyond that of the rectangular grid.