26

I have a polygon:

Polygon[{{0, 200 }, {200, 100}, {500, 300}, {100, 700}}]

How can I figure out its area? The docs page does not have any example.

So far I've reached this point with no success:

Needs["Polytopes`"]
Area[Polygon[{{0, 200 }, {200, 100}, {500, 300}, {100, 700}}]];

Concerning Area, the documentation states:

Area[polygon]
$\ \ \ \ \ $ gives the area of polygon polygon, when the edges of polygon have unit length.

So it is possible that my question really should be how to set unit length on edges of polygon?

m_goldberg
  • 107,779
  • 16
  • 103
  • 257
d.k
  • 485
  • 4
  • 9

4 Answers4

22

I prefer PolygonArea myself, but for version 7 users, there's this function by Mr.Wizard for non-intersecting polygons:

polygonArea = 
 Compile[{{v, _Real, 2}}, 
   Block[{x, y},
    {x, y} = Transpose[v]; 
    Abs[x.RotateLeft[y] - RotateLeft[x].y]/2
   ]
 ]

It gives the same answer as the undocumented built-in (as it should).

rm -rf
  • 88,781
  • 21
  • 293
  • 472
20

Basing on undocumented function introduced by J. M. in this Q&A:

pts = {{0, 200}, {200, 100}, {500, 300}, {100, 700}};

Graphics`Mesh`MeshInit[];
PolygonArea[pts]
155000.

Usage of undocumented functions is usualy useful but keep in mind that it may not work with future versions or with all cases. On the other side, it may work. One just can't be sure and trust them too much. ;)

Kuba
  • 136,707
  • 13
  • 279
  • 740
  • when I tried pts = {{5, 2}, {4, 1}, {1, 3}};

    GraphicsMeshMeshInit[]; PolygonArea[pts] I got -2.5. I don't understand.

    – minthao_2011 Jun 24 '14 at 15:49
  • @minthao_2011 the order does matter. Try PolygonArea[Reverse@pts]. If it is only a matter of clockwise or anticlockwise order you can use Abs. – Kuba Jun 24 '14 at 16:02
14

I cannot resist. Writing the code rm -rf posted was one of my first Mathematica programming exercises from over eleven years ago. (Boy, time flies.) Here's a copy of the old Notebook, which I kept, and yes, these are the actual notes I wrote myself. (I do not attest to their present accuracy, only their historical record.)


Polygon

Area of non-self-intersecting polygons, described by a set of {x,y} points, using the direct Determinant method. In this version, emphasis was placed on conciseness of code.

polyarea = Abs@Tr[Det /@ Partition[#, 2, 1, 1]]/2 &;

Again, the Determinant method, but in a semi-explicit form that is somewhat more efficient.

polyarea = Abs[Tr[#*#4 - #2*#3 & @@@ Partition[Flatten[#], 4, 2, 1]]/2] &;

These are compiled versions of the prior two functions, respectively. Of note is that the version using Det is only marginally improved with Compile, while the other becomes several times more efficient. Viewing the compiled code will show that Det is apparently not actually compiled (it is explicit). Also note the changes that were made to each function to conform to the constraints of Compile.

polyarea = 
  Compile[{{v, _Real, 2}}, 
   Abs@Tr[Det /@ Partition[Append[v, v[[1]]], 2, 1]]/2];

polyarea = 
  Compile[{{v, _Real, 2}}, 
   Abs[Tr[#[[1]]*#[[4]] - #[[2]]*#[[3]] & /@ 
       Partition[Flatten[Append[v, v[[1]]]], 4, 2]]/2]];

Updated May 26, 2002.

In this function the Determinant method is optimized using Dot-products.

polyarea = 
  Block[{x, y, R = RotateLeft}, {x, y} = Thread@#; Abs[x.R@y - R@x.y]/2] &;

This compiled version of the Dot-based function is nearly twice as efficient as the non-compiled version. Amazingly, this makes it over 30 times as fast as the direct Determinant approach.

polyarea = 
  Compile[{{v, _Real, 2}}, 
   Block[{x, y}, {x, y} = Transpose@v; 
    Abs[x.RotateLeft@y - RotateLeft@x.y]/2]];

By the way, these days I would use Module for the non-compiled version; I used to abuse Block rather badly.

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
  • 2
    My first Mathematica notebook should be burned and the ashes of the bytes scattered across the Pacific Ocean. – rm -rf Aug 28 '13 at 01:01
  • @rm-rf Not proud of them, eh? ;-p Mind you this wasn't my first attempt at Mathematica programming, rather one if my earliest exercises. I don't think I kept any of my first attempts, and besides, at the beginning I thought Mathematica was just a big calculator; I didn't realize you could program with it right away. – Mr.Wizard Aug 28 '13 at 01:05
  • @rm-rf p.s. I'm now digging through the archives trying to find the oldest thing I have that vaguely qualifies as programming. – Mr.Wizard Aug 28 '13 at 01:07
  • 1
    @rm-rf I may have found it; my first use of anything besides an explicit formula followed by Solve or Plot: Table[Rationalize[N[Pi],10^-d],{d,1,5}] <--- look Ma, Programming!! lol – Mr.Wizard Aug 28 '13 at 01:13
  • 3
    Heh, I don't have my first ones, but it probably was something along the lines of For[... For[... mat[[i,j]] = RandomReal[];]] :P – rm -rf Aug 28 '13 at 01:23
  • @rm-rf Lol. This was exactly how I used Mathematica until I joined this site earlier this year. – RunnyKine Aug 28 '13 at 02:07
7

In version 10, many graphics primitives, including Polygon, can be treated as geometric regions. Use RegionMeasure:

poly=Polygon[{{0, 200 }, {200, 100}, {500, 300}, {100, 700}}];

RegionMeasure[poly]
(* 155000 *)
Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263
  • Region`RegionMeasure[poly] works in version 9.0.1.0 (possibly in earlier versions, too) -- +1. – kglr Jun 25 '14 at 08:47