0

I have the plane points pi i=1,...,n and they form a simply closed but not necessarily convex curve. The curve from pi to p(i+1) and from pn to p1 is the straight line. I need an algorithm to compute the area contained.

Henrik4
  • 464
  • 3
  • 13
  • [wikipedia Polygon Area](https://en.wikipedia.org/wiki/Polygon#Area) – Ripi2 May 05 '20 at 15:56
  • For simple, non-intersecting polygons (convex or non-convex) the simplest method to calculate area is explained very well [here](https://alienryderflex.com/polygon_area/). This is known as the [Shoelace formula](https://en.wikipedia.org/wiki/Shoelace_formula) – RaffleBuffle May 05 '20 at 17:06
  • @Ripi2 has given you a (fairly) simple way to calculate it using an equation. If that is allowed, that is *much* simpler than any algorithm... – shapiro yaacov May 05 '20 at 17:41

1 Answers1

0

Let us break down the problem into much smaller, manageable ones.

The idea:
Break it down into triangles and sum their area. In every iteration get a point that is convex (in relation to the one before and after), get the area of that triangle (area(p(i), p(i-1), p(i+1))) and remove that point from the list of relevant point still to be handled.

On the topic of checking if a point is inside a convex polygon, I'll assume the points are going clockwise (if not, reverse them of swap the condition on the angle). Basically, given p(i), p(j), p(k) where i + 1 = j and j + 1 = k (consecutive), the angle between the ledges edge(i, j) and edge(j, k) will tell us if p(j) is concave or convex. This solution can be seen here

totlaArea = 0
listOfPoints = inputtedPoints

getThreeAdjacentPoints(listOfPoints, index) {
  n = listOfPoints.length
  point1 = listOfPoints[pointIndex]
  point2 = listOfPoints[(pointIndex + 1) % n]
  point3 = listOfPoints[(pointIndex - 1) % n]
  return { point1, point2, point3 }
}

getTriangleArea(listOfPoints, index) {
  { point1, point2, point3 } = getThreeAdjacentPoints(listOfPoints, index)
  return calculateTriangleArea(point1, point2, point3)
}

getNextConvexPointIndex(listOfPoints) {
  for index in listOfPoints.length - 1:
    { point1, point2, point3 } = getThreeAdjacentPoints(listOfPoints, index)
    angleBetweenEdges = getAngle(edge(point3, point1), edge(point1, point2))
    if angleBetweenEdges < 180:
      return index

  // Will never actually reach here unless code error:
  return -1
}

while listOfPoints.length > 2:
  pointIndex = getNextConvexPointIndex(listOfPoints)
  triangleAreaOfPoint = getTriangleArea(listOfPoints, pointIndex)
  totalArea += triangleAreaOfPoint
  listOfPoints.remove(pointIndex)

I don't have a mathematical proof at hand, but I'm pretty sure that taking any polygon, it's made up of convex triangles that can be found in the method I describe.

Hope this was helpful.

shapiro yaacov
  • 2,308
  • 2
  • 26
  • 39
  • I'm almost sure this method does not work with not-convex polygons. – Ripi2 May 05 '20 at 16:00
  • @Ripi2 Since you're always taking only a point that is convex in relation to the adjacent points, I'm pretty sure it is. You keep slicing off convex pieces from the original polygon until it's all gone. – shapiro yaacov May 05 '20 at 16:05
  • Maybe, if you show how `getNextConvexPointIndex` fulfills. – Ripi2 May 05 '20 at 16:09
  • @Ripi2 I do. There is a link to how to check if a point is in a convex polygon. Take *a* point you want to check, and use the code in the link with the point in question and *all other points of our polygon*. – shapiro yaacov May 05 '20 at 17:17
  • @Ripi2 - found a better way, updating the question shortly – shapiro yaacov May 05 '20 at 17:25
  • @Ripi2 Done. Got a nice way to find a point that is convex with relation to its neighbours. – shapiro yaacov May 05 '20 at 17:38