views:

498

answers:

2

Hi

Is there a automatic way to get all the points of an ellipse stroke, without the filling points.

Thanks in advanced

A: 

By using Reflector I found out that there is a GetPointList() method in the EllipseGeometry class unfortunately it's private. Maybe you can invoke it through reflection but that's sounds like a very bad hack... I'll see if I find another way...

Jalfp
Its enough for my POC
JP
+2  A: 

In WPF there are no actual "Points" in a geometry - it is infinitely smooth. This can be seen by zooming in on an ellipse. You can go to 1,000,000x zoom and you can still see curvature and no points.

Since WPF shapes aren't composed of points, your question can be interepted in several ways. You may be looking for any of these:

  • A list of points that approximates the boundary of the ellipse (polyline approximation)
  • A set of pixels covered by the ellipse including the fill
  • A set of pixels covered by the edge of the ellipse

Here are the solutions in each case:

If you're looking for an approximation of the ellipse as discrete points (ie. a dotted-line version that looks like an ellipse), use this code:

  PolyLineSegment segment = 
    ellipse.DefiningGeometry
      .GetFlattenedPathGeometry(1.0, ToleranceType.Absolute)
      .Figures[0].Segments[0] as PolyLineSegment;

  foreach(Point p in segment.Points)
    ...

If you're looking for the pixels affected, you'll need to RenderTargetBitmap:

  RenderTargetBitmap rtb =
    new RenderTargetBitmap(width, height, 96, 96, PixelFormat.Gray8);
  rtb.Render(ellipse);
  byte[] pixels = new byte[width*height];
  rtb.CopyPixels(pixels, width, 0);

Any nonzero value in pixels[] is partially covered by the ellipse. This will include points interior to the ellipse if the ellipse has a fill.

If you need to get only the pixels along the edge but your ellipse is filled, or vice versa, you can create a new Shape to pass to RenderTargetBitmap:

  var newEllipse = new Path
  {
    Data = ellipse.DefiningGeometry,
    Stroke = Brushes.Black,
  };
  RenderTargetBitmap rtb = ...
    [same as before]
Ray Burns
Wow, thanks for the details !
Jalfp