26
$\begingroup$

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?

$\endgroup$
2
  • $\begingroup$ Area of polygon = 1/2 apothem * perimeter * height $\endgroup$
    – user9316
    Commented Sep 1, 2013 at 13:11
  • 1
    $\begingroup$ Area command was introduced on July 9th, 2014; Area[Polygon@pts]. $\endgroup$
    – Syed
    Commented Sep 15, 2023 at 14:16

4 Answers 4

20
$\begingroup$

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

$\endgroup$
2
  • $\begingroup$ when I tried pts = {{5, 2}, {4, 1}, {1, 3}}; GraphicsMeshMeshInit[]; PolygonArea[pts] I got -2.5. I don't understand. $\endgroup$ Commented Jun 24, 2014 at 15:49
  • $\begingroup$ @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. $\endgroup$
    – Kuba
    Commented Jun 24, 2014 at 16:02
22
$\begingroup$

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).

$\endgroup$
5
  • 1
    $\begingroup$ This algorithm is given in Mathworld. $\endgroup$ Commented Aug 27, 2013 at 23:05
  • 4
    $\begingroup$ polygonArea is 3 times fast in my test. And even more with CompilationTarget->"C" $\endgroup$
    – Murta
    Commented Aug 27, 2013 at 23:35
  • $\begingroup$ Heh -- I wrote this ten years ago. I'm glad it's still serviceable. +1 of course. :^) $\endgroup$
    – Mr.Wizard
    Commented Aug 28, 2013 at 0:36
  • 1
    $\begingroup$ @Mr.Wizard Let's see... 10 years ago, I did not know a single programming language. In fact, I had not written a single line of code in any language and had not even considered using a computer for programming :D $\endgroup$
    – rm -rf
    Commented Aug 28, 2013 at 0:41
  • $\begingroup$ By the way, you're making me feel old. :-p $\endgroup$
    – Mr.Wizard
    Commented Aug 28, 2013 at 1:22
14
$\begingroup$

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 - [email protected]]/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 - [email protected]]/2]];

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

$\endgroup$
6
  • 2
    $\begingroup$ My first Mathematica notebook should be burned and the ashes of the bytes scattered across the Pacific Ocean. $\endgroup$
    – rm -rf
    Commented Aug 28, 2013 at 1:01
  • $\begingroup$ @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. $\endgroup$
    – Mr.Wizard
    Commented Aug 28, 2013 at 1:05
  • $\begingroup$ @rm-rf p.s. I'm now digging through the archives trying to find the oldest thing I have that vaguely qualifies as programming. $\endgroup$
    – Mr.Wizard
    Commented Aug 28, 2013 at 1:07
  • 1
    $\begingroup$ @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 $\endgroup$
    – Mr.Wizard
    Commented Aug 28, 2013 at 1:13
  • 3
    $\begingroup$ Heh, I don't have my first ones, but it probably was something along the lines of For[... For[... mat[[i,j]] = RandomReal[];]] :P $\endgroup$
    – rm -rf
    Commented Aug 28, 2013 at 1:23
7
$\begingroup$

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 *)
$\endgroup$
1
  • $\begingroup$ Region`RegionMeasure[poly] works in version 9.0.1.0 (possibly in earlier versions, too) -- +1. $\endgroup$
    – kglr
    Commented Jun 25, 2014 at 8:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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