Assuming that the polygon does not self-intersect, what would be the most efficient way to do this? The polygon has N vertices. I know that it can be calculated with the coordinates but is there another general way?
-
1Other than using the coordinates?? – Beta Dec 17 '15 at 04:55
-
Let me introduce you to http://math.stackexchange.com where people answer nicely math questions. – Déjà vu Dec 17 '15 at 05:28
-
6@ringø This is a perfectly good programming question. Nothing against you personally, but SO folks who think any problem that involves a bit of math isn't programming are really doing the community a disservice. – Gene Dec 17 '15 at 05:40
-
1@Gene Not at all. Some matish questions (complexity, game theory...) often find a pragmatic answer here on SO (without too much theory and integrals involved). For this particular question, however, which should be a piece of cake for mathematicians, and for which the arithmetic formula is likely to be easily programmable, and immediately checked and confirmed by other fellow mathematicians, math.SE was a good bet, imo. Nothing against you personally, this is what I'd have done. Pure gracious advice... no other intention ... – Déjà vu Dec 17 '15 at 05:59
-
What have you tried so far? Also, adding some pretty pictures will help others visualise your problem. – Wai Ha Lee Dec 17 '15 at 16:58
4 Answers
The signed area, A(T)
, of the triangle T = ((x1, y1), (x2, y2), (x3, y3))
is defined to be 1/2 times the determinant of the following matrix:
|x1 y1 1|
|x2 y2 1|
|x3 y3 1|
The determinant is -y1*x2 + x1*y2 + y1*x3 - y2*x3 - x1*y3 + x2*y3
.
Given a polygon (convex or concave) defined by the vertices p[0], p[1], ..., p[N - 1]
, you can compute the area of the polygon as follows.
area = 0
for i in [0, N - 2]:
area += A((0, 0), p[i], p[i + 1])
area += A((0, 0), p[N - 1], p[0])
area = abs(area)
Using the expression for the determinant above, you can compute A((0, 0), p, q)
efficiently as 0.5 * (-p.y*q.x + p.x*q.y)
. A further improvement is to do the multiplication by 0.5
only once:
area = 0
for i in [0, N - 2]:
area += -p[i].y * p[i+1].x + p[i].x * p[i+1].y
area += -p[N-1].y * p[0].x + p[N-1].x * p[0].y
area = 0.5 * abs(area)
This is a linear time algorithm, and it is trivial to parallelize. Note also that it is an exact algorithm when the coordinates of your vertices are all integer-valued.

- 75,459
- 18
- 120
- 173
-
This is the best answer, but you should expand the A() function. Also note that it doesn't matter what you use for p[0] in those A() calls, so you might as well use (0,0) constant and save a few operations – Matt Timmermans Dec 17 '15 at 13:11
-
Very interesting. If all you need is to know the total area of the polygon (like the OP in this case), I guess performing an actual triangulation is overkill after all (although it _is_ straightforward to calculate the total area from the individual triangles once you've done it). – Nicolas Miari Dec 24 '15 at 01:28
-
Here is a one-line Matlab version of this: area = abs(sum(sum(vertices .* (circshift(vertices, [1 0]) * [0 1;-1 0]))))/2; – Jed Jun 19 '20 at 16:51
The best way to approach this problem that I can think of is to consider the polygon as several triangles, find their areas separately, and sum them for the total area. All polygons, regular, or irregular, are essentially just a bunch of triangle (cut a quadrilateral diagonally to make two triangles, a pentagon in two cuts from one corner to the two most opposite ones, and the pattern continues on). This is quite simple to put to code.
A general algorithm for this can be coded as follows:
function polygonArea(Xcoords, Ycoords) {
numPoints = len(Xcoords)
area = 0; // Accumulates area in the loop
j = numPoints-1; // The last vertex is the 'previous' one to the first
for (i=0; i<numPoints; i++)
{ area = area + (Xcoords[j]+Xcoords[i]) * (Ycoords[j]-Ycoords[i]);
j = i; //j is previous vertex to i
}
return area/2;
}
Xcoords
and Ycoords
are arrays, where Xcoords
stores the X coordinates, and Ycoords
the Y coordinates.
The algorithm iteratively constructs the triangles from previous vertices.
I modified this from the algorithm provided Here by Math Open Ref
It should be relatively painless to adapt this to whatever form you are storing your coordinates in, and whatever language you are using for your project.

- 2,764
- 3
- 21
- 29
-
i don't think there's anything wrong with your answer. those are signed trapezoid areas, not triangles, and it's perfectly fine if they overlap. if fact, if the vertices are stored as 2d vectors with cross product operator defined, it can even be simplified to sum(v[i] ^ v[i+1]) – Anton Knyazyev Dec 17 '15 at 11:10
-
-
-
1@Jed I'm open to corrections if you spotted an error (I did this back in High School and I wouldn't exactly be surprised if something was sloppy), but after a cursory glance and trying a couple examples, I think the math is fine here. What's an example where this wouldn't work? Note that the order of Xcoords and Ycoords shows the order they connect in, which I never seem to have clarified. – rp.beltran Jun 20 '20 at 17:53
-
1@rp.beltran. My apologies... you are absolutely right! Timothy Shields' answer is equivalent to yours even though they are formulated quite differently. I still (very slightly) prefer his answer since each increment to the area is the (signed) area of a triangle connecting the 2 segments with the origin (after the /2), which makes it more intuitive to me. Yours still gives the same answer once you add it all up, though. Thanks for helping me see my error :-) – Jed Jun 21 '20 at 18:37
-
1@Jed no problem, always glad to have more eyes checking things! I think I prefer his answer too, especially since I feel like my explanation was lacking. I just wanted to make sure there was nothing technically inaccurate. – rp.beltran Jun 22 '20 at 19:14
- Take 3 consecutive points from the polygon.
- Calculate the area of the resulting triangle.
- Remove the middle of the 3 points from the polygon.
- Do a test to see if the removed point is inside the remaining polygon or not. If it's inside subtract the triangle area from the total, otherwise add it.
- Repeat until the polygon consists of a single triangle, and add that triangle's area to the total.
Edit: to solve the problem given by @NicolasMiari simply make two passes, on the first pass only process the vertices that are inside the remainder polygon, on the second pass process the remainder.

- 1
- 1

- 299,747
- 42
- 398
- 622
-
1
-
1From the question: "what would be the most efficient way to do this?" The straightforward implementation of this is as least O(N^2). Why all the upvotes on an answer that gives a highly suboptimal algorithm to a problem that has a known, simple O(N) solution? There is *nothing* harder about getting the area of a nonconvex polygon compared to a convex polygon, the optimal algorithm is actually the same in both cases. Yet the question and top-ranked answer would suggest to anybody just skimming that you need a complex algorithm to handle the nonconvex case. This is very misleading. – Timothy Shields Dec 17 '15 at 20:36
-
@TimothyShields my algorithm is intuitive, yours is not, but your link to wikipedia helps a lot. Don't worry, cream rises to the top. – Mark Ransom Dec 18 '15 at 03:40
-
@SGR step 4 might be a little slow, but I think there's a way to speed it up if you know whether the vertices are ordered clockwise or counter-clockwise. Other than that it should be O(n). – Mark Ransom Dec 18 '15 at 03:46
-
You are not guaranteed to have a convex polygon after one pass, so even with two passes you can end up with a situation similar to what Miari showed. In fact, there is not finite number of passes that will guarantee a convex polygon in general, so this algorithm seems a bit awkward. The Shields algorithm is quite straight forward and intuitive. – Jed Jun 21 '20 at 18:56
The "Tear one ear at a time" algorithm works, provided the triangle you remove does not contain "holes" (other vertices of the polygon).
That is, you need to choose the green triangle below, not the red one:
However, it is always possible to do so (Can't prove it mathematically right now, but you'l have to trust me). You just need to walk the polygon's vertices and perform some inclusion tests until you find a suitable triple.
Source: I once implemented a triangulation of arbitrary, non-intersecting polygons based on what I read in Computational Geometry in C by Joseph O'Rourke.

- 16,006
- 8
- 81
- 189