Continuing my series of posts on "gee, that's obscure," I thought I'd document the difference between miter limits in both Adobe Illustrator and the Windows Presentation Foundation (WPF). I ran into these differences while building my export plug-in, and they caused me a bit of pain.
Both Illustrator and WPF support miter limits for connected line segments. Miter limits control how "pointy" your segments look where they're joined. Because miter limits in both Illustrator and WPF are relative to the thickness of the line, they are naturally more noticeable with larger stroke widths. For thick line segments that meet at very acute angles, the join can be very pointy...so much that it can look quite ridiculous. Miter limits allow you to control when Illustrator and WPF decide to trim—or bevel—the join.
The two illustrations below show example miter limits and how they're handled by both systems. The actual content that is rendered to the screen is shown in black. Blue represents the line centers.
Before we talk about limits, we need to understand the miter length. Miter lengths are measured differently between Illustrator and WPF. In Illustrator, the miter length is measured from the inside of the join to its outside point. In WPF, it's measured from the center of the join to its outside point. This effectively means that a miter length in WPF is half of what it would be in Illustrator.
Miter limits are represented by ratios. In Illustrator, the default miter limit is 4, and the limit specifies a threshold. Essentially, a miter limit of 4 says: "if the miter length of this join is greater than 4 times my line thickness, bevel it; otherwise, allow the mitered join." In the left diagram, the dashed horizontal lines are each one line thickness away from each other. Notice that the miter length of the first join exceeds 4 times the thickness of the line. Because of this, Illustrator will bevel the join. The miter length of the second join falls below 4, so it is mitered (pointy). So, miter limits in Illustrator represent an either/or situation; either the line is beveled at the center of the join, or it is mitered. There is no in between.
In WPF, the miter limit is used to clamp the miter length. The miter limit represents a ratio of the miter length to half of the line's thickness. In the right diagram, the dashed horizontal lines are each one half line thickness away from each other. The first join has a miter limit of 3, so it is beveled (trimmed) at 3 times one half of the line thickness. The second join is beveled at 2 times one half of the line thickness. Notice that—unlike Illustrator—miter limits in WPF are not treated as a threshold; they simply specify where to limit the miter.
It's certainly possible to mathematically determine an equivalent miter limit between a single join in Illustrator and WPF. But, because most figures are made up of many joined line segments, and miter limits in WPF are set on the figure, there is no way to specify different miter limits for each join. This is precisely why my Illustrator to XAML Export Plug-In takes a conservative approach and specifies a miter limit of 1, thereby preventing the extremely pointy miters that would result for very acute angles. In retrospect, I suppose that setting a miter limit that is half that of Illustrator's might be a reasonable alternative.
So, if you do notice some extra beveled lines in your exported artwork, you should first try removing the miter limit setting from your XAML. If the results are unsatisfactory, you'll need to play with the setting until you achieve visually desirable results.
Special thanks to fellow Microsoft employee, Anthony Hodsdon, for his help in clarifying the WPF behavior.
Seriously obscure, however, a very useful tip. Thank you for the information.
PingBack from http://www.m-atolye.com/index.php/2009/05/illustrator-stroke-1/
PingBack from http://www.m-atolye.com/index.php/2009/05/illustrator-stroke-2/
At last I have got how it does work! It isn't obscure. Before I supposed this miter limit is connected somehow with an angel between line segments.
thanx for the inlightenment ! no one in class new what the miter limit was or its purpose ! thank you for clarifying it !
Very interesting. Does anyone happen to know the answer to the following related questions:
Does WPF's "Bevel" behaviour ignore MiterLimit and always use what could be described as "MiterLimit=0"?
Why does WPF clamp the MiterLimit to at least 1?
The "System.Drawing.Drawing2D.LineJoin.MiterClipped" behaviour looks closer to what Illustrator does. Any particular reason why it is not in WPF?
Thanks for the info; very handy.
I found that if I have (for example) a horizontal line with a 180 degree join to another horizontal line, the line is effectively extended by the miter limit. This is definitely a problem for XAML that has been generated from some other format.