tags:

views:

387

answers:

3

I'm drawing a whole bunch of Polygons onto a canvas, most of which share an edge with at least one other Polygon. I'd like to indicate a Polygon is "special" by outlining it, however due to the overlapping edges the Stroke on a Polygon tends to be partially drawn over by another Polygon causing the Stroke to look thinner than it should in places. Additionally, depending on draw order, a Polygon may have its Stroke almost entirely covered by those around it. Spacing the Polygons out is not a very attractive option, as visible gaps between Polygons are much less preferable to this "thin stroke" problem.

I reason that the effect I'm looking for can be achieved by generating each Polygon as a pair of Polygons instead, such that one Polygon is completely contained within the other and this smaller Polygon's Stroke runs up to (but does not overlap) the outer Polygon's Stroke. The inner Polygon would have a transparent Fill at all times, and a non-transparent Stroke only when I wish to indicate that the now pair of Polygons are "special".

My question boils down to; how can I derive such an inner Polygon from the outer one, or failing that how else might I achieve this effect?

The Polygon's in question can be constrained to the regular polygons if need be, and the Strokes are simple 1 thickness solid lines with no fancy miters or the like. I'd like to be able to adjust the thickness of the Stroke at some point, but nothing fancier than that.

A: 

Can you control the drawing order so the special polygons are drawn last?

John Kugelman
There are a lot of Polygons involved, so it'd be expensive. There's also no guarantee they don't border each other.
Kevin Montrose
+1  A: 

I think there's actually a few ways to achieve what you want.

First, going with your original idea of drawing a second, slightly smaller polygon within the original polygon; it's not a bad idea. To answer your original question as to how to generate the smaller polygon: you can find the centroid of each polygon, and offset each vertex by a percentage of the distance to that centroid point of the polygon to get the smaller polygon. This should give a pleasing effect.

Another way you could go would be to use z-order, and offset the "thicker" polygon by a slight negative z-distance.

Yet another way to go would be to exploit draw order; draw your thicker polygons last, which will prevent them from being overdrawn by the surrounding polygons.

Yet another idea that might work depending on your needs might be not to draw polygons at all, but to draw a series of lines, simply thickening some of the lines.

There's a lot of options for you to try; hope you find one that works out well!

McWafflestix
Your scaling idea is interesting, I'll play around with it to see if its workable. Z-order and draw order manipulations will fail if two "special" polygons border each other, which is not uncommon enough to be acceptable I suspect. Thickening lines is also interesting, but I worry about the performance costs.
Kevin Montrose
Drawing lines of varying thickness should be considerably faster than drawing polygons, since you're drawing once instead of twice for each shared edge.
McWafflestix
I ended up going with a slight variation on your first suggestion. Rather than scaling down, I did some trig to figure out exactly how far to move each point towards the "center" so that the new point was StrokeThickness away from the old one.
Kevin Montrose
A: 

The polygon offsetting problem is discussed here: http://stackoverflow.com/questions/1109536/an-algorithm-for-inflating-deflating-offsetting-buffering-polygons