Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Basic Calculation for WPF Polygon: Area and Centroid

The System.Windows.Shapes.Shape namespace provides access to Polygon object that can be used in XAML or code.

Is there a Microsoft library that provides some very basic calculations on a Polygon like area or centriod?

My preference is to not re-implement these functions myself or copy a math/geometry library.

like image 966
Zamboni Avatar asked Dec 12 '10 18:12

Zamboni


2 Answers

The RenderedGeometry property returns a Geometry object, which itself has a GetArea method.

There doesn't seem to be anything to compute the centroid, but it should be quite easy to do, based on the Points property of the 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));
like image 58
Thomas Levesque Avatar answered Nov 07 '22 03:11

Thomas Levesque


I posted some linq-ified geometric operations in this post:

How to Zip one IEnumerable with itself

The centroid computation I posted is different from the one that @Thomas Levesque posted. I got it from Wikipedia - Centroid. His looks a lot simpler than the one that I posted.

Here is my algorithm (it makes use of SignedArea and Pairwise from the link above):

  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); 
  } 

There are also some other algorithms at that link that you might find useful.

like image 20
wageoghe Avatar answered Nov 07 '22 01:11

wageoghe