Базовый расчет для полигона WPF: площадь и центр тяжести - PullRequest
5 голосов
/ 12 декабря 2010

Пространство имен System.Windows.Shapes.Shape предоставляет доступ к Полигону объекту, который можно использовать в XAML или коде.

Существует ли библиотека Microsoft, которая предоставляет некоторые очень простые вычисления для многоугольной области или центриода?

Я предпочитаю не реализовывать эти функции самостоятельно или копировать библиотеку математики и геометрии.

Ответы [ 2 ]

9 голосов
/ 12 декабря 2010

Свойство RenderedGeometry возвращает объект Geometry, который сам имеет метод GetArea.

Кажется, что нет ничего для вычисления центроида, но это должно быть довольно легко сделать, основываясь на свойстве Points Polygon:

Point centroid =
    polygon.Points.Aggregate(
        new { xSum = 0.0, ySum = 0.0, n = 0 },
        (acc, p) => new
        {
            xSum = acc.xSum + p.X,
            ySum = acc.ySum + p.Y,
            n = acc.n + 1
        },
        acc => new Point(acc.xSum / acc.n, acc.ySum / acc.n));
2 голосов
/ 12 декабря 2010

В этом посте я опубликовал несколько геометрических операций linq-ified:

Как застегнуть один IEnumerable с собой

Вычисление центроида, которое я опубликовал, отличается от того, которое опубликовал @Thomas Levesque. Я получил это из Википедии - Centroid . Он выглядит намного проще, чем тот, который я выложил.

Вот мой алгоритм (он использует SignedArea и Pairwise по ссылке выше):

  public static Position Centroid(IEnumerable<Position> pts) 
  { 
    double a = SignedArea(pts); 

    var  c = pts.Pairwise((p1, p2) => new  
                                      {  
                                        x = (p1.X + p2.X) * (p1.X * p2.Y - p2.X * p1.Y),  
                                        y = (p1.Y + p2.Y) * (p1.X * p2.Y - p2.X * p1.Y)    
                                      }) 
                .Aggregate((t1, t2) => new  
                                       {  
                                         x = t1.x + t2.x,  
                                         y = t1.y + t2.y  
                                       }); 

    return new Position(1.0 / (a * 6.0) * c.x, 1.0 / (a * 6.0) * c.y); 
  } 

По этой ссылке есть и другие алгоритмы, которые могут оказаться полезными.

...