I need to extract the coordinates from a 2D polygon then calculate the maximum and minimum of the x and y coordinates. I know it sounds simple, but I've found it impossible to do so far. Below is my code:

a = Cases[poly, {_ , _}, Infinity];

coord = Table[{a[[x,1]]*1, a[[x,2]]*1}, {x, 1, Length[a], 1}];


Where poly is a predefined polygon. The outcome of the Min function is this:

A very large output was generated. Here is a sample of it. 
Min[ -43.7405, <<143>>, 
     Polygon[{{151.137, -34.062}, {151.137, -34.062}, {151.137, -34.0619}, <<14319>>,
              {151.137, -34.0622}, {151.137, -34.0621}, {151.137, -34.062}}]]

The same thing happens if I leave out the line of code that uses Table to create coord, and instead just try to calculate the minimum of a. This one has got me completely stumped. Any help would be greatly appreciated.


Ok here's the output of FullForm[poly]

A very large output was generates. Here is a sample of it:

List[ List[Polygon[  List[List[151.228, -33.956], List[151.228, -33.9561], 
      List[151.226, -33.9563], <<976>>, List[151.229, -33.9559], 
      List[151.228, -33.956], List[151.228, -33.956]]], <<1388>>, List[<<1>>]]
  • 1
    $\begingroup$ Since you created the polygon, then you must have its coordinates already? it helps to post a complete self contained example that shows the order of the operations, and not bits and pieces since that makes it hard to follow the logic. $\endgroup$ – Nasser Feb 22 '14 at 10:08
  • $\begingroup$ You really need to consolidate everything into your question, i.e. get rid of those two pseudo-answers. Otherwise this thread will remain a mess. $\endgroup$ – Yves Klett Feb 22 '14 at 12:02
  • $\begingroup$ It looks like your poly expression contains a list of length 2 at a higher level than the individual coordinate pairs that you are trying to reach with Cases. Try making the pattern inside Cases more specific, e.g. {_Real, _Real} $\endgroup$ – Simon Woods Feb 22 '14 at 12:41

It appears your data poly is not in the form you think it is. So without a specific example at hand, I will give a fairly general solution, which is not hard to do.

  • First extract each Polygon directive from the graphics data.
  • Each Polygon may contain more than one polygon: separate them.
  • Find the x and y bounds of each polygon.

For the graphics, I'll use the shape of Italy from CountryData. It consists of three polygons.

bounds[coords_?(MatrixQ[#, NumericQ] &)] := Module[{x, y},
   {x, y} = Transpose[coords];
   {{Min[x], Max[x]}, {Min[y], Max[y]}}

italy = CountryData["Italy", "Shape"];

directives = Cases[italy, Polygon[pts_, ___] :> pts, Infinity]; (* strip any options *)
polygons = Cases[directives, _?(Depth[#] == 3 &), Infinity];
ranges = bounds /@ polygons
   {{{-0.0763244, 0.0757934}, {-0.0848148, 0.0742848}},
    {{-0.0621578, -0.0398592}, {-0.067826, -0.0264755}},
    {{-0.00564986, 0.0386553}, {-0.107569, -0.0784857}}}


   MapThread[{#1, EdgeForm[#1], Rectangle @@ Transpose@#2} &,
     {{Red, Yellow, Blue}, ranges}]

Mathematica graphics

| improve this answer | |

The output of Fullform shows that your poly variable is not just a Polygon but is actually a list containing, among other things, the Polygon.

Even though Graphics is showing your Polygon, if you hover over the actual graphic I expect you'll see it complain:

"... is not a Graphics primitive or directive".

To extract the Polygon and then the points, do this:

poly = poly[[1,1]];
points = poly[[1]];

To understand what I did above, you should read up on Expressions, especially the tutorials.

As rasher hinted in his comment, you can get the minimum and maximum x- and y-coordinates as below:

{xmin, xmax, ymin, ymax} = {Min[points[[All, 1]]], 
  Max[points[[All, 1]]], Min[points[[All, 2]]], Max[points[[All, 2]]]}

There are more concise ways to do this, but I think this will be more understandable.

| improve this answer | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.