2013-04-29 176 views
8

所以我已经在javascript中获得了这个代码来从网络中计算不规则的多边形区域。计算多边形区域

function polygonArea(X, Y, numPoints) 
{  
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 + (X[j]+X[i]) * (Y[j]-Y[i]); 
     j = i; //j is previous vertex to i 
    } 
    return area/2; 
} 

var xPts = [3, 3, 2, 2, 3, 3, 6, 6, 9, 9, 4, 4 ]; 
var yPts = [2, 4, 4, 5, 5, 6, 6, 5, 5, 3, 3, 2]; 

var a = polygonArea(xPts, yPts, 4); 
alert("Area = " + a); 

结果似乎是正确的。如果按顺时针方向追踪顶点,它将显示正的结果,但如果我以逆时针方向追踪顶点,它将变为负值。为什么?

该算法如何工作?我真的很想知道它背后的数学解释是什么,因为我仍然很难理解网络上的解释。

+1

这很可能是更适合于http://programmers.stackexchange.com/ – 2013-04-29 17:55:17

+0

其实,这个问题将是programmers.se一个糟糕的配合比stackoverflow。 – comingstorm 2013-04-29 20:52:27

+1

如果明显更多,怎么能只有'4'点? – mikemaccana 2015-06-16 09:25:19

回答

13

想象一下,从每个顶点到Y轴绘制水平线;对于每个边缘,这将描述一个梯形:

Y-axis 
^ 
| 
|--------o (X[j], Y[j]) 
|   \ 
|   \ 
|   \ 
|------------o (X[i], Y[i]) 
| 
+----------------------------> X-axis 

在内部循环的公式计算(X[j]+X[i]) * (Y[j]-Y[i])这个梯形如果Y[i] <= Y[j]两次的区域中,或两倍如果Y[i] >= Y[j]区域。

对于封闭多边形,这自然会从“下降”边缘的区域减去“上行”边缘左侧的区域。如果多边形是顺时针的,则整齐地切出多边形的精确(加倍)区域;如果逆时针方向,你会得到负面(加倍)的区域。

为了计算给定的多边形的面积,

Y-axis 
^ 
| 
|  o------o 
|  |  \ 
|  |  \ 
|  o   \ 
|   \   o     
|   \  /
|   \ /
|   \ /
|    \/
|    o 
| 
+-------------------------> X-axis 

采取下行面积:

Y-axis 
^ 
| 
|--------o------o 
|    \ 
|     \ 
|  o   \ 
|     o     
|    /
|    /
|    /
|    /
|--------------o 
| 
+-------------------------> X-axis 

减去上行面积:

Y-axis 
^ 
| 
|--------o  o 
|  | 
|  | 
|  o 
|   \   o     
|   \ 
|   \ 
|   \ 
|    \ 
|--------------o 
| 
+-------------------------> X-axis 

虽然上述示例使用了凸面多边形,这个区域的计算对任意多边形都是正确的,而不管有多少个上下线他们可能有。

+1

谢谢你。这张图真的有助于:) – 2013-05-05 14:08:05

1

这里没有魔术。只要有一个看一个矩阵(http://en.wikipedia.org/wiki/Determinant#2.C2.A0.C3.97.C2.A02_matrices)的决定

编辑:

说实话:有这个代码一些magick:

  1. 任何您需要的三角测量。在这里:我们创建三角形,从(0,0)开始,有(Xi, Yi)(Xj, Yj)
  2. 您计算每个三角形的行列式以获得:Xi Yj - Xj Yi。但是这里有人计算(X[j]+X[i]) * (Y[j]-Y[i]) = Xj Yj - Xj Yi + Xi Yj - Xi Yi = (Xj Yj - Xi Yi) + (Xi Yj - Xj Yi)。但是,如果你把所有这些部分加入(Xj Yj - Xi Yi)就可以取消自己了。所以这是棘手的部分。
0

它累积每个定向段P [i],P [i + 1]和Y轴之间的符号区域。在循环结束时,多边形外面的区域将被抵消(它将被计数两次,并且具有不同的符号),并保留内部的有符号区域。

5

有一个算法来计算多边形面积:

function calcPolygonArea(vertices) { 
    var total = 0; 

    for (var i = 0, l = vertices.length; i < l; i++) { 
     var addX = vertices[i].x; 
     var addY = vertices[i == vertices.length - 1 ? 0 : i + 1].y; 
     var subX = vertices[i == vertices.length - 1 ? 0 : i + 1].x; 
     var subY = vertices[i].y; 

     total += (addX * addY * 0.5); 
     total -= (subX * subY * 0.5); 
    } 

    return Math.abs(total); 
}