Connect them … where?

If we want to stitch glyphs into a single path , we’ll need to find lines where we can connect them. In our list of drawing commands, these lines are denoted by a special marker I call a breakpoint.

Above is the middle glyph for curly brackets. To a human (and likely a machine learning algorithm), it’s pretty easy to spot where the breakpoints should be. The top and bottom ends of the character, right? But, should the wedge in the middle be a breakpoint too? What rules could we have to solve this algorithmically?

Rule 1

To start, what do all three of these potential breakpoints have in common?

All three lines are line butts, meaning we’ll have to consider the adjacent lines as well. Since the line drawing commands have a specific order & direction, a simple test for a butt is to check the directions of the adjacent lines.

For the breakpoint lines themselves, we need them to be completely horizontal or vertical.

These are where the first rule came from.

Rule 1: (a) The adjacent lines can’t point in the same direction. (b) The breakpoint line must be exactly horizontal or vertical.

Rule 2

Second, imagine a square bracket. The long vertical line that makes up the bracket is straight, and the adjacent lines point in different directions. By our ruleset right now, this would count as a wide breakpoint. That’s not what we want.

What if Rule 2 was, then, “The length of the breakpoint line must be shorter than both adjacent lines?” Consider the following.

If you look at this glyph instead, we can identify the ledge in the top-right corner to be a breakpoint. Rule 1 succeeds without issue, however, Rule 2 would fail because the line under the breakpoint is shorter than itself.

What should I do then? If we make Rule 2, “The length of the breakpoint line must be shorter than one of the adjacent lines,” it would be pretty easy to find a counterexample.

Here’s what I came up with (it’s a little messy):

Rule 2: Make sure the breakpoint line is …(a) shorter than one of the adjacent lines (b) make sure the other adjacent line multiplied by 1.5 is larger than the breakpoint line.

Rule 3

With my original proposition, one question is left: “Should the wedge in the middle be a breakpoint too?”

Right now, it passes both of our tests! But seeing as these wedges weren’t useful for stitching, I decided to detect and remove them.

Before when talking about how each breakpoint is a line butt, I failed to clarify that there were two types.

The first, called line caps, are the butt of a single line. Line caps include the top and bottom of this glyph.

The second is called a line join, and these connect two different lines. Line joins include the wedges I’ve talked about.

Since I only wanted line caps, I just needed a test that checked for single lines. This observation makes up the third rule.

Rule 3: The breakpoint line and its adjacent lines should “always” make a parallelogram.

Just how is this test implemented? According to Wolfram Mathworld, adding two adjacent angles in a parallelogram should equal 180 degrees. Given that the glyphs wouldn’t be perfect, I gave this comparison +/- 5 degrees of error. Using the breakpoint line and its adjacent lines, you can use the Law of Cosines to find these angles.

a dot b = ||a|| * ||b|| * cos(angle)

These three rules encompass what I implemented to detect breakpoints.