The Art Of Eyeballing – Part IV: The Stroke (Optics)

Index

Introduction | Learning To See | Overshooting | The Stroke: Optics


This is the first article of three, in our series, to talk about the stroke.

We briefly introduced the idea (in the previous article) that the stroke width has an effect on perception and, for this reason, should be adjusted. So, this article is just about that: optical adjustments to stroke.

May I state it right now: this is not rocket science and the more elaborated considerations about stroke (such as modulation, for example) will be covered in the next articles. For now, we want to approach a very simple case – a monoline construction – and try to achieve balance.

And without further ado (and because I’m starting to feel way to serious while writing this), let’s skip to the good part.

1. Horizontal vs. Vertical

stroke_slide_01

Let’s get right to it: in the image above, which are the thickest strokes? Vertical or horizontal? Take your time. Horizontal, right?

If you thought “they’re equal”, you’re right. But do they seem equal? To me, they don’t. And to most people, they also don’t.

But for many years, I simply trusted the computer. And, as always, the computer was right, so who was I to judge mathematical perfection? Well, this is about perceptual balance, not the first. Again, trust your eyes.

And here’s a correction (with horizontal strokes being about 1% thinner than the vertical ones):

stroke_slide_02

But why does this happen? In honesty, I don’t really know, although I have some theories about it:

  1. We have two eyes, distributed horizontally, making our area of eyesight wider than taller; and this might add relevance to vertically distributed elements;
  2. In type, we have millennia of broadnib and flat brush writing, usually with 30 to 40º angle from an horizontal position, making horizontal strokes wider than vertical ones. But again, this could be due to a perception/optical/neurological phenomena.

If you’re wondering about how this works in typefaces, have a look here:

2. Orthogonal vs. Diagonal

Consider the following example:

stroke_slide_04

Again, all the 3 lines have exactly the same stroke width. We already talked about how to compensate the horizontal line, so let’s just do that:

stroke_slide_05

If it wasn’t obvious in the first image, now it is: the diagonal line also looks heavier than the orthogonal ones.

So, for comprehension’s sake, let’s give the diagonal line the same stroke width has the (already compensated) horizontal line:

stroke_slide_06

… which makes the diagonal line too thin.

Before we get into the solution, I’d like you to consider a couple of things:

So, if neither of the horizontal nor the vertical strokes’ width is applicable to the 45º diagonal (which, again, is half-way rotated between the orthogonal axis), what happens if we pick the exact in-between stroke width? Here you go:

stroke_slide_07

Does it look alright? *wink*

And now, you might be asking about other angles. If we apply the same width stroke to any diagonal, we get this:

stroke_slide_08

If you compare the first two lines, the second looks too thin; and if you compare the last two, the former looks too thick.

So here we can start to acknowledge that the thickness of a diagonal line should vary according to it’s angle, and that it’s a progression between the horizontal and vertical widths.

Here’s a linear progression of angles and widths:

stroke_slide_09

2.1 Tackling Slants and Widths

If you’re anything like me, by now you’re doing some stressful mental schemes on how to calculate the exact width of a diagonal, depending on the horizontal and vertical strokes’ widths.

So, in order to save you some stressful times, here’s a quick and dirty way to do it:

  1. Draw an ellipse that has the same width as the vertical stroke and the same height as the horizontal stroke;
  2. Adjust the strokes to be tangents to this ellipse.

Two steps method. This is what I call workflow optimization! Here’s a visual representation of the method:

stroke_slide_10

And, to implement a tradition, here are these principles applied to type:

stroke_slide_11

3. Straight vs. Curve

And we’re coming closer to an end.

Let’s start with the following image, where all the strokes are exactly the same (and the O is already overshot):

stroke_slide_12

And now, let’s make the corrections that we already know about (horizontal and vertical, in this case):

stroke_slide_13

Same kind of question: do the straight and curved strokes feel equal? You might want to take a step back it see the images from afar.

The H seems to pop out more that the O. And, as I mentioned, the O is already overshot, so it’s not a case of overshooting. Or is it?

Well, curves seem thinner that straight lines for the same reason we have to overshoot them: a lot of white space is created and positive mass is decreased, so we have to compensate for that.

But the thing to retain here is that curves seem thinner than straight lines and the amount of compensation needed isn’t as extreme as the one we do in the verticle / horizontal cases, so it’s closer to an overshooting compensation.

Let’s correct our example:

stroke_slide_14

4. How Much?

If you’ve noticed, I wasn’t blunt about how much to compensate; in fact, I only gave one example in §1.

I could provide rules-of-thumb that would be percentage ranges of compensation, but I feel that this is a trap.

First (and again), I advise you not to make calculations; providing you such rules (on how much to compensate) would oblige you to make these calculations and I want you to design as freely as you can.

So take what you’ve learned today and trust you’re eye. If it looks awkward, well, it’s awkward. Teach yourself to pay attention to the forms, counterforms and whitespace. Inspect the curve/line segments on by one and compare them to the whole form. And to the whole group of forms.

Even if we dabble in maths and geometry, here, keep in mind that these are means to an end, not the end itself.

I hope you’ve enjoyed this article, see you in the next one! Cheers!


References:

Bézier OCD Or Why You Should Know About Point Placement

0. Introduction

If you’ve been visiting this blog, you might be wondering why I’m writing another article about this subject.

You’ve probably read Bézier Curves And Type Design: A Tutorial and Bézier Curve Quick Tips: Two Methods For Smooth Curves, along with AGSC’s article So What’s the Big Deal with Horizontal & Vertical Bezier Handles Anyway?, and you might think that, for graphic designers and related métiers, things are pretty much covered.

Well, they’re not. The suggestions to keep nodes at extrema, handles vertical or horizontal, use explicit inflection points, balance the handles and so on aren’t just workflow optimizations: they’re methods to overcome technical problems.

So, today, I want to give you the reasons why these point-placement methods should be used extensively, in a more in-depth way than in the previous two articles (and again, here and here, because I strongly suggest you to read them before reading this one).

Ready? Go!

1. It Reduces Point Placement

This one is a no-brainer. As discussed before, in cubic Bézier curves, the most simple way to describe a curve is with two nodes and two handles, and if we keep angles smaller than 90º, we can easily draw any curve. So, working with extra points doesn’t seem much of an advantage, since it ends up with you having more stuff to deal with.

1.1 And Thus, It Reduces File Size

Less points, less coordinates. Less coordinates, smaller file size. Done.

2. Rasterizers Are Dumb

This section and §3 are this article’s gem: the stuff that you don’t usually see being talked about.

In Bézier Curves And Type Design we barely scratched the surface on this. Remember how a cubic Bézier curve is constructed? The animations there show how a Bézier curve rasterizer builds a curve through a method called linear interpolation. Let’s start there.

2.1 Linear Interpolation

Linear interpolation is a method of curve fitting that uses linear polynomials (read line segments joined together to fit a curve), and this is how computers draw Bézier curves, because De Casteljau’s algorithm (the one used in Bézier curves) was made to do precisely this.

So, as we know the Bézier Curves And Type Design‘s animations, the curve is broke into several linear steps. Have a look:

interpol01

Fibonacci FTW!

Be aware that the subdivisions are per segment: from anchor point to anchor point.

So, with this said, how would the previous animation look with odd point placement? Here you go:

interpol02

As you might have guessed, the perceptual smoothing of each segment through the various iterations differ quite a bit:

Ever worked with splines in 3D software? If you have, you know the pain it is (or used to be, rasterizers did get better) to convert it to a mesh, with steps unequally distributed along the spline. Or Flash, that converts the curves to line segments for processing and file size’s sake. Now you know why.

How to solve this? Same recomendations:

2.2 And Rasterizers Should Be Dumb; You’re The One Who Should Be Smart

Why? Because linear interpolation isn’t the only thing to worry about, when it comes to rasterizers.

We want our vector drawings to be cross-compatible between formats, rasterizers, hinters, printers, parsers, and the list goes on. So it’s our job to know a little bit more and try to minize conversion errors. Just because something looks good in Illustrator, it doesn’t mean that it will look good in an old printer.

And if you convert your drawing from cubic to quadratic and back to cubic and then interpolate it, welcome to hell.

3. Hinting

Though this part is somewhat related to §2, it deserves a different section.

Let’s get this straight: hinting is not exclusive to type design; in truth, every printer, for example, only prints bitmaps, i.e., it hints the vector artwork first. And printers may have their own rasterizers and hinters, and the way you draw can make a difference.

The reason why it’s an obvious type concern is that we (type designers) deal with a finer degree of detail in way smaller sizes.

But, in spite of rasterizers becoming better and better, it doesn’t mean that graphic designers shouldn’t be concerned about it too.

And with this I don’t mean that we should rasterize vector work and start editing pixels: you should, however, try to draw vector art as fool-proof as you can.

Can the way you draw influence hinting? Yes, very slightly, but yes. And the smaller you get, the more crucial it becomes.

4. Conclusion

I hope you’ve enjoyed reading this! Happy drawing!

Cheers!

Bézier Curve Quick Tips: Two Methods For Smooth Curves

Fixing curves, for me, is an every day activity. Sometimes they look oddly pointy, too steep or too wide, guiding my eyes to awkwardness.

And since I’m an optimization freak (as you could tell on my previous article on Bézier curves), I end up using some procedures to tackle problems.

So, today I want to share with you a couple of techniques I use a lot. Here we go!

1. Method 1

If you’ve read my article on Bézier curves (and you should for the sake of understanding this article), you’ve noticed that I stressed on how important point placement is. Here’s a summary of what I recommended:

  1. Keep nodes at the extrema;
  2. Keep handles vertical or horizontal (with the obvious exception of corners);
  3. Use explicit inflection points.

But this doesn’t mean that you should immediately start drawing this way; these are only requirements for you final work.

With this said, consider the following lowercase n:

bezier2_001

As you can see, those curves are in terrible shape, due to unfortunate point placement, resulting in pointy areas. So, how do we solve this?

Let’s start by fixing the top curve:

bezier2_002

Here’s what happened:

And here’s the same process for the inside curve:

bezier2_003

And a comparison between our original n and our corrected one:

bezier2_004

So, what happened here? Here’s some observations:

  1. Manipulating two handles is way easier than four handles and an anchor;
  2. This method provides us a way to find the optimum position for where the extreme anchor should go;
  3. We let the point addition algorithm find out the best handle position for us;
  4. Even if we need to do some minor adjustments, it’s easier and safer to adjust a respectable curve than a clumsy one (I know I’m personalizing the curves, I know).

1.1 Problems With This Method

This has some limitations, of course:

  1. It’s not adjustment proof: You might still need to do adjustments to the curve. But hey, you’re closer than you were! And prepare yourself for §2, it might come in handy;
  2. It doesn’t work very well with angles above 180º: For the same reason that we can’t use this method with quadratic Bézier curves, we would need 4th or higher-order Bézier curves to use this method with a fair degree of control. And in plain English: this works with parallel handles or with a smaller angle, because otherwise, you’re no able to control the curve’s extension and steepness. And here’s an animated GIF, because you guys love these things:
bezier2_005

2. Method 2

And here we are. *awkard stare*

So, back to business: how do the point-addition algorithms distribute the handle length? Well, they keep the handle length proportionally equal, to keep the curve as smooth as possible.

With this in mind, when we have our handles in a 90º angle, we can fit our 4 points in a square. And with less than 90º, a trapezoid:

bezier2_006

Let’s stick with the rectangle, for simplicity’s sake.

By now, your inquisitive mind might be asking:

What happens to the curve if one handle grows from the minimum to the maximum length, inscribed in the rectangle, while the other does the opposite?

And now you must be thinking how did I read your thoughts, right? Right.

But let’s not deviated from the subject; here’s what happens:

bezier2_007

As you can see, the curve bulges slightly in the extended handle’s side and gets steeper in the retracted one.

Now, what happens if both handles go from minimum to maximum length?

bezier2_008

You probably saw this coming.

Well, first of all, I apologize for the slow build up, but I wanted you to be aware of the two factors, because you’ll be dealing with them with this method.

By the way, I don’t know if you keep the habit of click-and-dragging curves, but if you don’t, start doing it. And in most drawing applications, holding the Shift key down keeps the handles in the same vector.

If we want to keep the handles’ lengths proportionally equal, the rectangle from their maximum length point to their actual position has to be proportional to the anchor’s rectangle. Here’s an image to clear this out:

bezier2_009

The effect that this has on this curve is minimum, but it distributes the curvature evenly.

So, here are the steps to do this:

bezier2_010
  1. Get an unevenly distributed curve;
  2. Extend the handles to their intersection point;
  3. Press the Shift key (to keep handles straight), click on top of the curve and drag it back. Gently tilt to the sides, trying to get both handles proportionally equal until you get the curvature you desire.

With practice, you’ll be able to eyeball the entire process and still get some sweet and smooth curves.

3. Final Thoughts

I hope you’ve found this article helpful, since I find these make me work faster (I struggle less to achieve satisfactory results), while it keeps the overall look of my work consistent.

Thanks for reading this and if you like it, share the knowledge! Cheers!

Bézier Curves and Type Design: A Tutorial

[2026/09/14]: This article became the most popular I've ever written. Since it was written a long time ago, I decided to rework it: polishing the wording to facilitate comprehension, fixing dead links and typos, and adding interactivity. Still, it remains faithful to the original — a lot of people discussed it and helped me flesh it out into what it became, and I want it to continue reflecting that process. Enjoy!

Whenever I am asked to assess the quality of a typeface or logotype, or when someone asks me for help with their typefaces, one of the most common problems I find is bad Bézier curve design.

And every single time this happens, it’s not people’s fault. It is a fatalism of existence: if people knew better, they’d do better. Surprisingly, it seems that a lot of people have trouble wrapping their heads around this: students struggle with it, fellow lecturers despair.

And then there’s that heart-stabbing situation when someone drops by and says “Hey, I just finished this font, can you have a look and see if something’s missing?” and I feel obliged to say, with grief, “You have to redesign it all over: it’s poorly designed, Bézier-wise”.

So, in order to save some people from this hassle, read along.

1. Problems

First of all, we should understand that each piece of desktop publishing software is going to compile the font files in its own way. Moreover, each one of them is going to convert the curves through its unique algorithm, sometimes unleashing hell.

Flash IDE [now Adobe Animate], for example, is notorious for wrecking curves. It does so based on the size of your vector artwork in order to keep the file as small as possible. If fonts are not embedded, the same happens.

Some programs, like 3D applications, simply break the curve into several facets. So even if you are doing something in Illustrator to use in 3DS Max, for example, read on; it might save you some trouble.

2. Reasons

Usually, all of this revolves around how PostScript and TrueType deal with outlines: TrueType uses quadratic Bézier curves, and PostScript uses cubic Bézier curves.

I know, I know, geek stuff. Here’s the simple explanation:

And for the visual type of person, here’s an image:

So, if we were to draw a circle in both curve equations, they would be drawn the following way:

Let’s count the number of points needed for each circle:

Counting points might seem unpractical and silly, but it can tell you a couple of things right away:

If this is so, it seems that cubic curves win over quadratic ones; so why aren’t quadratic curves obsolete?

3. Digging deeper

But how are Bézier curves calculated? Let’s start with quadratic curves.

3.1 Quadratic Curve rasterization

We have our three points: two anchors (in and out) and one control point. Let’s call the anchors A1 and A2, and call the control point C. Next, let’s connect A1 to C and C to A2 with straight lines, as shown below:

Drag the orange points to reposition them.

Now, we’ll add two points: one that travels from A1 to C and another that travels from C to A2, and they’ll take exactly the same time to make their trip. And for the sake of this exercise, we’ll also add a straight line that connects the two traveling points (shown in black, below):

Drag the orange points to reposition them.

Again, let’s add a new point, one that travels between the two black points, taking the same time to travel from one point to another (shown below in white). If we track its path while traveling, voilà, we have our quadratic curve rasterized:

Drag the orange points to reposition them.

OK, so now you know how a computer renders a Bézier curve:

3.2 Cubic Curve rasterization

So, what about cubic curves? Is the rasterization done the same way?

Well, yes, sort of. It just adds another level of our “traveling points”. Have a look:

Drag the orange points to reposition them.

See what they did there? Right, a moving quadratic curve inside a cubic one!2 Here’s some deductions on cubic curve rasterization:

3.3 Going back and forth

The addition of multi-order intermediate points can go down to infinity, and it’s possible to break cubic curves into quadratic with minimal loss in quality. The other way around, well… it gets tricky.

Quadratic curves are always conic sections, while Bézier curves that have more than one level are a result of curve funkiness, meaning, a collage of cone sections’ sections.

So if we were to write an algorithm to convert cubic curves to quadratic, we would have no problem: we would just check for cone sections that would fit on that curve.

But if we were to write one to convert quadratic to cubic, the best the program could do is an approximation of the original outline, usually keeping the anchor points it already had, but adding one more control point per anchor. So, file size wise, not a good idea; processing power wise, even worse.

Edit: As it was stated over at Hacker News by simias and jacobolus, and kindly explained by nanofortnight, the above statements are wrong — in fact, the truth is the very opposite.

If we were to convert a quadratic curve to cubic, it would be the exact same curve, as nanofortnight demonstrated. But, as jacobolus pointed out, due to the integer structure of font compiling, this conversion might not be exact.

And when we go to convert cubic curves to quadratic, it’s not as easy-peasy as I stated above. For further reading on this, check this out.

Is this a problem, then? Well, these conversion issues are the reason why DTP software and printers favour PostScript, i.e., cubic Bézier curves. If the drawing was provided in quadratic curves, the software could easily convert them to cubic; if it was already in cubic, it would simply keep it that way.

So, while designing type, you opt either for TrueType or PostScript. And, while this makes me favour PostScript, if you start with one, stick with it.

But why do type design applications offer cubic curves only or have them as default, as a drawing method? Well, as debated, conversion from TrueType to PostScript is optimal and the other way around is not. And the third reason comes next.

4. File Size

We already know that you can draw the same thing with cubic curves using fewer points, but there are also some other things that we can take into consideration, regarding file size.

4.1 Always work with integers

FontLab [Studio3], for example, doesn’t even let you use decimal coordinate data, and no sane developer will build a vector drawing application that would allow point data to infinity. Since we still need a worldwide network of computers just to find some more pi digits, no one gets to treat themselves to perfect circles.

But then again, if your eye can’t tell the difference and, in fact, you still have to cheat the circle to make it look like a circle (when you adjust forms optically), using decimal numbers on type design is just some sort of geek stubbornness.

And there’s the workflow issue: ask any professional type designer if they use Illustrator — or another vector drawing application that uses decimal numbers by default — and you’ll find that very few say yes; and even those who do still have to adjust their drawings in a font editor.

It’s way easier to nudge with the keyboard arrows than to use a text box to input integer values. On the other hand, a lot algorithms used for font handling in DTP software simply round the points to integers, so they can handle them with less storage and processing resources.

Edit: And, as Pomax kindly pointed out, the OpenType specs only allow for integer point coordinates anyway.

But the big issue here is file size: if you have a file with integers and 4 points, it will be smaller than a file with two decimal figures and 2 points. Make some thousands of points and the difference in file size balloons, as well as processing requirements.

5. Always work with cubic curves

Cubic curves win, for all the reasons mentioned above: easier to draw with [there are more reasons for this, keep reading], better conversion to quadratic than the other way around, smaller file size. You know the drill.

But it is also worthy of note that this is why cubic is the safe default when we start drawing fonts — conversion to quadratic is lossless, so your outlines are always reproducible by other tools and designers.

6. Keep anchor points at extrema – and handles straight

This is a big one. Most of the time, the most common problem I see is that the anchor points are haphazardly positioned, spread all over the place. This results in jagged lines, poor rasterization, bigger file sizes (who hasn’t tried to fix something by adding more, right?), increased difficulty in drawing, and the list goes on.

If you want to draw a smooth curve, having the anchor points at the horizontal and vertical extrema and keeping the handles vertical or horizontal is enough. It gives you better control over the curve path and less stuff to adjust: it keeps most of your curve segments under 90º and transitions predictable.

Edit: And, although implied above, is good to mention: do not invert the path direction with your handles (thanks to Pedro Amado for pointing that out). Here’s what I mean:

Keep in mind that we’re talking about what should be in your final output. Although I recommend keeping your placements tidy and as close as possible to what it should be, inverting the direction like in the image above can be a way to draft quickly4.

Edit: 7. Explicit Inflection Points

Hrant Papazian made me notice, on Twitter, that I’ve missed a point (pun intended!). The example above, on the right, lacks an explicit inflection point.

“What the hell is that?”, you may ask. Well, in an ideal scenario, all points should alternate between vertical and horizontal handle position. Why? Because we want to keep each curve segment without inflection points, in order to have an optimal conversion from cubic to quadratic.

“OK, lovely, but you haven’t explained what an inflection point is”. True. Here it is: the inflection point is where the curve changes direction. So, if you’re walking from left to right and start leaning to the left, the place where you start doing so is your path’s inflection point5. Simple.

So, in the example in §6, the curve changes paths between the two horizontal handles, creating an inflection point. How to avoid it? Well, make it explicit; i.e., add an anchor point in that location. This way, the curve is split into one-direction-only segments:

bezier010

For more  information on inflection points, have a read here.

Edit: Also worthy of note, pay attention to how the handles retract at every step of the way. Even if you thought “Yeah, of course it does” — kudos to you, tap yourself in the back on my behalf — the bounding box for coordinate control also got smaller. This makes our life easier while editing: we get a better view to what we’re doing.

8. Final considerations

I know this was lengthy and somewhat technical, but I believe it’s important to know why instead of just how. Computers have limitations – and will always have – so it’s important to make the best of it; and for that, knowledge is key.

I hope you had as much fun reading this as I had making this article. Thanks for your time!


References:

  1. Anchor node is a general term for insertion and end points of a curve segment. Since the curve always goes through these, they “anchor” the curve to it. ↩︎
  2. This algorithm for drawing/splitting curves is de Casteljau’s algorithm. ↩︎
  3. FontLab has supported floating point coordinates since version VI. But it still compiles to integers. Just a relic of how long ago this was written. ↩︎
  4. Let me also state that whenever I do this, I add the extrema points right away: there’s not much control in drawing such a huge angle and inversion with just two points, especially when it comes to curve tension. ↩︎
  5. I encourage you to go back to §3.2, where you have the interactive cubic curve animation. Drag points around so that you have a curve and countercurve and pay attention to the gray line — you can see exactly when the curve “flips” direction. ↩︎