如何计算非凸多边形的面积?

时间:2015-12-17 04:39:17

标签: algorithm

假设多边形不会自相交,那么最有效的方法是什么?多边形有N个顶点。 我知道它可以用坐标计算,但还有另一种通用方法吗?

4 个答案:

答案 0 :(得分:3)

三角形A(T)签名区域T = ((x1, y1), (x2, y2), (x3, y3))被定义为以下矩阵的行列式的1/2倍:

|x1 y1 1|
|x2 y2 1|
|x3 y3 1|

决定因素是-y1*x2 + x1*y2 + y1*x3 - y2*x3 - x1*y3 + x2*y3

给定由顶点p[0], p[1], ..., p[N - 1]定义的多边形(凸面或凹面),您可以按如下方式计算多边形的面积。

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)

使用上面的行列式表达式,您可以有效地将A((0, 0), p, q)计算为0.5 * (-p.y*q.x + p.x*q.y)。进一步的改进是仅将0.5乘以一次:

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)

这是一种线性时间算法,并行化很简单。另请注意,当顶点的坐标都是整数值时,它是一个精确的算法。

Link to Wikipedia article on this algorithm

答案 1 :(得分:2)

  1. 从多边形中取3个连续点。
  2. 计算结果三角形的面积。
  3. 从多边形中移除3个点的中间部分。
  4. 进行测试以查看移除的点是否在剩余多边形内。如果它在里面从总数中减去三角形区域,否则添加它。
  5. 重复直到多边形由一个三角形组成,并将该三角形的区域添加到总数中。
  6. 编辑:解决@NicolasMiari给出的问题只需进行两次传递,在第一次传球时只处理里面剩余多边形的顶点,在第二次传递过程中剩下的

答案 2 :(得分:1)

我能想到的解决这个问题的最佳方法是将多边形视为多个三角形,分别找到它们的区域,并将它们作为总面积求和。所有多边形,规则的或不规则的,基本上只是一堆三角形(沿对角线切割四边形以形成两个三角形,从一个角到两个最相对的两个切口中的五边形,并且图案继续)。这很容易放到代码中。

此算法的一般算法可编码如下:

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;
}

XcoordsYcoords是数组,Xcoords存储X坐标,Ycoords是Y坐标。

该算法迭代地构造前一个顶点的三角形。

我从提供的Here by Math Open Ref

算法中对此进行了修改

将其调整为您存储坐标的任何形式,以及您为项目使用的任何语言,都应该相对轻松。

答案 3 :(得分:1)

“一次撕一个耳朵”算法可行,前提是您删除的三角形不包含“孔”(多边形的其他顶点)。

也就是说,您需要选择下面的绿色三角形, 不是红色的三角形:

enter image description here

然而,总是可以这样做(现在不能用数学证明它,但你必须相信我)。您只需要走多边形的顶点并执行一些包含测试,直到找到合适的三元组。

来源:我曾根据我在Computational Geometry in C by Joseph O'Rourke中读到的内容实施了任意非交叉多边形的三角测量。