views:

331

answers:

3

I am seeing the weirdest bug with the following code.

I have a PathGeometry to which I added a PathFigure so that I can add LineSegments to it.

This is what I do:

_pathGeometry.Figures.Add(_pathFigure);
_pathFigure.StartPoint = new Point(4, 0);
LineSegment lineSegment1 = new LineSegment(new Point(4, -10), true);
LineSegment lineSegment2 = new LineSegment(new Point(4, 0), true);
_pathFigure.Segments.Add(lineSegment1);
_pathFigure.Segments.Add(lineSegment2);

I then draw it:

using (DrawingContext drawingContext = RenderOpen())
   drawingContext.DrawGeometry(null, _pen, _pathGeometry);

What I should see:

WPF should draw a vertical line that goes from 0 to -10 and back to 0. The last part (back to 0) cannot be seen because it's drawn on the same x pixel. But the last part causes the following:

What I see:

WPF draws a line that goes from 0 to -15. It makes no sense to me. This 5 pixel difference happens whenever I draw a vertical line on top of another vertical line as in the previous example.

Please someone tell me I made a mistake and this is not a WPF bug.

A: 

If it is anything like GraphicsPath, you will need to set the end point too.

leppie
The last LineSegment is always the end point.
Hermann
A: 

Ok, I found a solution to this problem myself. It does seem to be a WPF bug.

You need to add the LineSegments to individual PathFigures to not see this strange behaviour:

PathFigure pathFigure1 = new PathFigure();
pathFigure1.StartPoint = new Point(4, 0);
LineSegment lineSegment1 = new LineSegment(new Point(4, -10), true);
pathFigure1.Segments.Add(lineSegment1);

PathFigure pathFigure2 = new PathFigure();
pathFigure2.StartPoint = new Point(4, -10);
LineSegment lineSegment2 = new LineSegment(new Point(4, 0), true);
pathFigure2.Segments.Add(lineSegment2);

pathGeometry.Figures.Add(pathFigure1);
pathGeometry.Figures.Add(pathFigure2);

I would still be grateful if someone could explain why I see this bug if I don't do it this way or if someone could confirm that this is a bug.

Hermann
+1  A: 

I think the issue has to do with how WPF renders "corners" in your Path. As the angle between two line segments becomes more acute, the corner rendering becomes more apparent.

In your case, you have a zero degree angle (a line segment folding back on itself), which is the most problematic case.

Not all is lost -- there several possible solutions:

  • Split the PathFigure into two PathFigures (which is your workaround). By doing this, you remove the corner, and thus the issue.
  • Set the Path's StrokeLineJoin property to Bevel instead of the Miter (the default). This will bevel corner appearance.
  • Lower the Path's StrokeMiterLimit. This will make the corner less "pointy", as the scientists say.
  • Tell the LineSegment to explicitly remove it's "corner-ness". You can do this by setting the IsSmoothJoin property to true.

For more information regarding StrokeLineJoin, see here. For an interesting post about how WPF renders Mitered corners, see here.

micahtan
I am ok with my workaround. Thanks for all the solutions. Very interesting to learn why this happens and how to work around it.
Hermann