Changing the characteristics of paths

It's possible to change the characteristics of Bezier paths via several methods. For example, we can change the thickness of a stroked path using the method –setLineWidth:, where the argument is a float indicating the width of the line in points. We can change the thickness of the lines of our triangle by adding the following just before we send a stroke message to triangle:

[triangle setLineWidth:10];

This will make our drawing look like the following:

Figure 3.

If you set the line width to 0 using this method, then the path will be stroked with the smallest width that can be displayed on the screen. I choose a thick line width here to bring out some features about the way path elements are joined to each other.

First, notice how the lower right vertex of the triangle is a very sharp point that extends far beyond what we originally intended for our triangle. The image below shows a thin green line superimposed on top of the thicker red line to highlight the effect I’m speaking of.

Figure 4.

The reason for this is that by default, lines in a path are joined together using a so-called miter join where the outside edge of the two intersecting lines are extended to a point. This default join style is defined the constant NSMiterLineJoinStyle, which we use to identify the join style in code. We can fix this problem in several ways.

One, we can change the line join style to either NSRoundLineJoinStyle or NSBevelLineJoinStyle using the method -setLineJoinStyle. For example, if we wanted to make the vertices rounded, we would pass the constant NSRoundLineJoinStyle as an argument to setLineJoinStyle:

[triangle setLineJoinStyle:NSRoundLineJoinStyle];

Alternatively, we can flatten the corners by using NSBevelJoinStyle. In the image below, I show the three line join styles side-by-side with a representation of the original path drawn in green.

Figure 5.

Line joining, however, is not the end of our woes here. Remember our discussion about closing paths and the line join issues associated with it? Well, here is a perfect example of what happens when the path is not officially closed, despite your shape having the appearance of being closed.

Notice in the lower left corner that the lines are never joined. The reason for this is simple enough: this corner is both the start of the path and the end of the path. We never say that these two points -- despite them being the same point -- should be joined. To fix this, we send a closePath message to triangle after our last construction command to close the path off, and now any join style will apply correctly, as shown below:

The end

So there you have it! This is how you can create any shape that you may need. NSBezierPath has many more methods that do useful things, many of which we will cover in future columns.

As always, I recommend that you become familiar with the NSBezierPath class reference if you haven’t done so already. For now, I leave you with these most useful tools with which you can do a lot. In the next column we will start to learn about how you can interact with elements of your drawing on screen using the mouse, so stay tuned for some good stuff. See you then!

Michael Beam
is a software engineer in the energy industry specializing in seismic application development on Linux with C++ and Qt. He lives in Houston, Texas with his wife and son.