views:

346

answers:

1

Using .NET's System.Drawing.Graphics GDI stuff, I have a shape consting of two arrays of points. They are the red and green pixels in the image below.

Now I am trying to fill the interior of this shape with a color. Drawing it as simple lines works just fine. Like this:

    g.DrawCurve(Pens.Red, points1);
    g.DrawCurve(Pens.Green, points2);

That gives the left image (1).

alt text

To fill this thing, I tried using a GraphicsPath like this:

   GraphicsPath gp = new GraphicsPath();
   gp.AddCurve(points1);
   gp.AddCurve(points2);
   g.FillPath(Brushes.Blue, gp);

It works... sorta. Problem is when the shape overlap itself as you can see in the middle image (2) and wont fill the overlapping part.

I tried using gp.widen() to get the outline and then fill after that:

      gp.Widen(new Pen(Color.Blue, 3));
      g.FillPath(Brushes.Blue, gp);

That ought to work, but it only seems to fill the 3-pixel slice outside the shape not the whole thing, as seen in the image (3).

Any ideas how to solve this?

+1  A: 

By default the GraphicsPath uses the FillMode.Alternate enumeration. You need FillMode.Winding

GraphicsPath gp = new GraphicsPath(FillMode.Winding);

The Winding mode considers the direction of the path segments at each intersection. It adds one for every clockwise intersection, and subtracts one for every counterclockwise intersection. If the result is nonzero, the point is considered inside the fill or clip area. A zero count means that the point lies outside the fill or clip area.

More info here

Michael G
I actually tried Winding mode earlier, but it completely messed up the fill. It eventually turned out to be a problem with last point != first point in the the arrays. So I reversed the points2 array and, lo and behold, FillMode.Winding works! I'll check in again tomorrow and mark this as answered (unless something else turns up :-)
Martin Wickman