计算多边形面积
Calculating Polygon Area
所以我已经得到这个代码在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);
结果似乎是正确的。如果沿顺时针方向描顶点,它会显示正的结果然而如果沿逆时针方向描顶点,它会变成负的。为什么会这样呢?
这个算法是如何工作的?我真的很想知道它背后的数学解释是什么,因为我仍然很难理解网上的解释
有一个计算多边形面积的算法:
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);
}
想象从每个顶点到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
虽然上面的例子使用了一个凸多边形,但是这个面积计算对于任意多边形都是正确的,不管它们可能有多少条上行和下行路径
下面是使用Andrii Verbytskyi的响应的代码片段:
/* Get area of a polygon/surface */
function area(polygon) {
let total = 0;
for (let i = 0; i < polygon.length; i++) {
const addX = polygon[i][0];
const addY = polygon[i === polygon.length - 1 ? 0 : i + 1][1];
const subX = polygon[i === polygon.length - 1 ? 0 : i + 1][0];
const subY = polygon[i][1];
total += (addX * addY * 0.5) - (subX * subY * 0.5);
}
return Math.abs(total);
}
function drawPolygon(context, polygon, strokeStyle, fillStyle) {
context.strokeStyle = strokeStyle;
context.fillStyle = fillStyle;
context.beginPath();
context.moveTo(polygon[0][0], polygon[0][1]); //first vertex
for (var i = 1; i < polygon.length; i++)
context.lineTo(polygon[i][0], polygon[i][1]);
context.lineTo(polygon[0][0], polygon[0][1]); //back to start
context.fill();
context.stroke();
context.closePath();
}
display = function(n) {
var context = document.getElementById("canvas").getContext("2d");
context.clearRect(0, 0, 500, 500);
drawPolygon(context, polygons[n], "#888", "#88f");
document.querySelector('span').textContent = area(polygons[n]);
};
const polygons = [
[[100, 100], [100, 300], [300, 400], [400, 250], [300, 0]],
[[300, 300], [300, 100], [0, 0], [-100, 400]],
[[50, 150], [200, 50], [350, 150], [350, 250], [250, 320], [200, 250], [150, 350], [100, 250]],
[[100, 100], [300, 100], [400, 300], [100, 300]]
];
const buttons = document.querySelectorAll("button");
for (let counter = 0; counter < buttons.length; counter++) {
buttons[counter].addEventListener("click", function(){
window.onload = display(counter);
});
}
window.onload = display(0);
<button onclick="display(0)">Polygon 0</button>
<button onclick="display(1)">Polygon 1</button>
<button onclick="display(2)">Polygon 2</button>
<button onclick="display(3)">Polygon 3</button>
Polygon area : <span id='area'></span>
<canvas id='canvas' width='400' height='400'></canvas>
这背后没有魔法。看看矩阵的行列式(http://en.wikipedia.org/wiki/Determinant#2.C2.A0.C3.97.C2.A02_matrices)
编辑:老实说:这段代码中有一些魔法:
- 你需要任何三角测量。这里:我们从
(0,0)
开始创建三角形,(Xi, Yi)
和(Xj, Yj)
- 你计算每个三角形的行列式得到:
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)
就消掉了。所以这是一个棘手的部分。
累计每个定向段p [i], p [i+1]与Y轴之间的带符号区域。在循环结束时,多边形外部的区域被消去(它将以不同的符号计数两次),而内部的带符号区域保留。
相关文章:
- 根据元素和容器大小计算边距
- 从Rally获取一个特定的标记,以便计算另一个字段中的值
- 使用D3.js计算带有字母间距的文本长度
- 使用CSS或JavaScript计算分页符的数量
- SVG/JavaScript:尝试选择和更改多边形点
- 可以't计算自定义谷歌地图的js
- 如何计算每个元素's的高度,并将这些值用作函数中的变量
- JavaScript计算帮助(乘以时间)
- 如何计算对象文字中的键
- 计算多边形是否足够大,可以在 gmap 上可见
- 计算多边形的面积
- Google MAPS API V3 -- > 如何计算多边形内的标记数量
- 使用JavaScript计算不规则多边形的面积
- Google Maps API 3:计算多边形的像素长度
- 计算多边形面积
- 计算两个旋转矩形/多边形的碰撞和相交面积
- 旋转多边形的计算
- 诺基亚Here地图计算多边形(如三角形)的质心会产生错误的结果
- 在JavaScript中计算两个多边形的重叠百分比
- 如何计算地图上的多边形面积