Обвързани точки с геометрична елипса

Има ли автоматичен начин за получаване на всички точки от щрих на елипса, без точките за запълване?


person JPP    schedule 29.10.2009    source източник


Отговори (2)


С помощта на Reflector разбрах, че има метод GetPointList() в класа EllipseGeometry, за съжаление той е частен. Може би можете да го извикате чрез размисъл, но това звучи като много лош хак... Ще видя дали ще намеря друг начин...

person japf    schedule 29.10.2009

В WPF няма действителни "точки" в геометрия - тя е безкрайно гладка. Това може да се види, като увеличите елипсата. Можете да преминете към 1 000 000x увеличение и все още можете да видите кривина и никакви точки.

Тъй като формите на WPF не са съставени от точки, вашият въпрос може да бъде прехванат по няколко начина. Може да търсите някое от тези:

  • Списък от точки, който приблизително приближава границата на елипсата (приближение на полилиния)
  • Набор от пиксели, покрити от елипсата, включително запълването
  • Набор от пиксели, покрити от ръба на елипсата

Ето решенията за всеки случай:

Ако търсите приближение на елипсата като отделни точки (т.е. версия с пунктирана линия, която изглежда като елипса), използвайте този код:

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

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

Ако търсите засегнатите пиксели, ще трябва да 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);

Всяка ненулева стойност в пиксели [] е частично покрита от елипсата. Това ще включва точки във вътрешността на елипсата, ако елипсата има запълване.

Ако трябва да получите само пикселите по ръба, но вашата елипса е запълнена, или обратното, можете да създадете нова фигура, която да предадете на RenderTargetBitmap:

  var newEllipse = new Path
  {
    Data = ellipse.DefiningGeometry,
    Stroke = Brushes.Black,
  };
  RenderTargetBitmap rtb = ...
    [same as before]
person Ray Burns    schedule 29.10.2009