March 12, 2006

Teri's Wisdom: Arrowheads Positioning

In perusing the Feature Requests posted on the Illustrator User to User forum, I came upon an interesting discussion with regards to how arrowheads are positioned at the ends of paths.

As you might already know, when you draw a path of a specific width, and then choose to add arrowheads (via the Filter > Stylize or Effect > Stylize menu), the arrowheads are added at the ends of the path. This makes the path longer than you actually specified and requires that you now make an adjustment to the path (such adjustments could be made easier when the Show Preview Bounds setting is used -- see Overstepping Your Bounds).

The feature request -- which make a whole lot of sense to me -- was centered on having Illustrator add arrowheads to a path without adding additional size to the path. I'm always fascinated as to how certain features or settings "came to be" in Illustrator, and when I worked on Illustrator, I tried to make a point of learning many of these settings, their causes, and their effects. However, I was never aware of the reason of why Illustrator drew arrowheads in this way. Which is why I have included Teri Pettit's explanation here, of why things are as they are. Teri's response is to a question that Jamees Talmage (JET) actually posed, in where he hypothesized on whether maybe arrowheads were drawn this way due to some legacy PostScript rules or regulations...

No, curiously enough, the actual code for positioning the arrowheads on the lines is flexible enough to handle arbitrary placements. It assumes that the backmost path in the arrowhead "design" is a straight stroked line in which the first endpoint should be placed on the endpoint of the path you are putting the arrowhead on, and the straight line should be made tangent to the path, sort of like it was a direction handle, and scaled so that the stroke weight of the guiding line is made the same as the stroke weight of the path you are applying the arrow to. When inserting an arrowhead, it copies the design definition, positions, scales and rotates the entire design by the same matrix that it uses to place the "guiding line", and then deletes the guiding line. (I looked into the code one day when I was trying to see how hard it would be to make the arrowheads be positioned at the endpoints.)

It is a mystery to me why the designers of the arrowheads in AI 5 decided to make those placement guidelines have their endpoints towards the back or center of the arrow instead of at the arrow tip. That's the only reason the arrowheads are getting placed past the end of the stroked path. The actual arrowhead designs were created not by engineers, but by a team of graphic artists, like the patterns and symbols are. So it was those artists who decided where the arrow tips should end, not the engineer writing the plugin filter.

But the filter was written a very long time ago (for AI 5), and hasn't been modified significantly since. (The live effects call the core of the corresponding filter code, not the other way around. When live effects came on the scene, what we mostly did was split each plugin filter into the part which found the selected objects, and the part which modified an object, and made the latter part be callable either by the filter on a selected object, or by the live effect on an object "under construction" by an appearance recipe. We didn't make hardly any changes to any of the actual "modify an object" code. There wasn't time to do so.) Way back in AI 5, there was no such thing as Symbols, and even pattern definitions were not yet accessible through the plugin API's. So the arrowhead "designs" are actually fragments of Illustrator 5 EPS syntax, similar to what got put on the clipboard, stored in the plugin's resource fork, indexed by the numbers that show up on the options dialog. And since plugins have no access to Illustrator's parser, the Arrowhead plugin has its own little mini-parser for a subset of the AI 5 Illustrator syntax, enough to cover paths with solid color strokes or fills.

So, we could make the arrowheads end on the lines simply by going in and modifying those fragments of AI 5 EPS in the resource fork to put the end of each positioning line at the tip of the arrow. But if that was all that was done, there would be backwards compatibility issues causing arrowhead effects saved by earlier versions to get repositioned. Which wouldn't be good, since usually the base path has been shortened to make the arrowhead end at the right place. So actually, you would want to leave the old designs as they were, and add new ones that would be available for newer files. But if you're going to go in and modify the Arrowhead filter, what you really want to do is make arrowhead designs be symbols, sort of like 3D bevels are, so that the user can define their own, and refer to them by name, not by a numerical index. Of course you'd still need to support the old indexed centered arrowheads for backwards compatibility.

Also, in order to keep the main stroke from sticking out past the arrow tips, you would want to do something to clip off any part of the main stroke past a certain point. (Actually, come to think of it, that might be part of the reason the positioning guidelines don't end at the arrow tip - because when the arrow tip got narrower than the stroke, you would be able to see the solid stroke sticking out at the edges. But there is still room in most of them to position the endpoint much closer to the tip than it is. It is usually quite far back, especially on designs like the pointing hand.) So the designs should probably contain another guideline besides the positioning one, which would be a "stroke clip point" guideline.

Teri goes on to mention that such a new feature would require some amount of work, and while it's certainly possible that such functionality might appear in Illustrator one day, it requires enough work in of itself that it must compete with other similar proposed new features and enhancements.


Newmango said...

For some time now I've abandoned both the Add Arrowheads Filter and Effect in favor of using a Brush. As a Pattern Brush, a stroke as the main element is stretched to meet an the inside edge of an arrowhead at either end, giving you a set that is exactly the length of the line.

I'd post the image here, but apparently the comments don't accept html tags, so -

Anonymous said...

CorelDraw solved this problem many versions ago, along with a lot of other totally annoying Illustrator problems. When I had to switch from Corel to Illustrator, I was amazed at the numerous gaffs that existing in Adobe's supposedly "premium" vector drawing program, especially since Corel had a reputation for being the less professional of the two programs. Illustrator has repeatedly refused to clean up a wide variety of problems that coulda/woulda/shoulda been solved (as part of a FREE update!!!)a long time ago. Good Morning Adobe...wake up please!