• ## 多边形面积的计算(C++实现) 计算几何 C++

438KB yang_deyuan 2020-12-29 17:03:39
• <!doctype html> <html lang="en"> <head> ...meta charset="UTF-8">... content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">...
<!doctype html>
<html lang="en">
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="data.js"></script>
<title>Document</title>
<body>

</body>
<script>
var s = "112.523197631836,37.868892669677734;112.5170669555664,37.8605842590332;112.52099609375,37.849857330322266;112.54137420654297,37.8512732521875;112.5351180302734,37.858699798583984";
console.log(computeSignedArea(cvpath(s)))
function cvpath(s) {
let path = s.split(';').map(item => {
return {
lng: item.split(',')[0]/1,
lat: item.split(',')[1]/1
}
})
return path
}
function computeSignedArea(path) {
let len = path.length
if (len < 3) return 0
let total = 0
let prev = path[len - 1]
let prevTanLat = Math.tan(((Math.PI / 2 - prev.lat / 180 * Math.PI) / 2))
let prevLng = (prev.lng) / 180 * Math.PI
for (let i in path) {
let tanLat = Math.tan((Math.PI / 2 -
(path[i].lat) / 180 * Math.PI) / 2)
let lng = (path[i].lng) / 180 * Math.PI
total += polarTriangleArea(tanLat, lng, prevTanLat, prevLng)
prevTanLat = tanLat
prevLng = lng
}
}

function polarTriangleArea(tan1, lng1, tan2, lng2) {
let deltaLng = lng1 - lng2
let t = tan1 * tan2
return 2 * Math.atan2(t * Math.sin(deltaLng), 1 + t * Math.cos(deltaLng))
}
</script>
</html>
<script>
var metersPerDegree = 2.0 * Math.PI * earthRadiusMeters / 360.0;
var radiansPerDegree = Math.PI / 180.0;
var degreesPerRadian = 180.0 / Math.PI;
var pointArr=[]
let d=data
console.log(d)
b(data)
function calculateArea(points) {
if (points.length > 2) {
var areaMeters2 = PlanarPolygonAreaMeters2(points);
// if (areaMeters2 > 1000000.0) {
areaMeters2 = SphericalPolygonAreaMeters2(points);
// }
}
}
function b() {
var s = "112.523197631836,37.868892669677734;112.5170669555664,37.8605842590332;112.52099609375,37.849857330322266;112.54137420654297,37.8512732521875;112.5351180302734,37.858699798583984";
//  let s=data
var s1 = new Array()
s1 = s.split(";");
for (var i = 0; i < s1.length; i++) {
var ss = s1[i];
var temp = ss.split(",");
var point = new Array();
point.push(Number(temp[0]), Number(temp[1]));
pointArr.push(point);
}
calculateArea(pointArr);
}
/*球面多边形面积计算*/
function SphericalPolygonAreaMeters2(points) {
var totalAngle = 0;
for (var i = 0; i < points.length; i++) {
var j = (i + 1) % points.length;
var k = (i + 2) % points.length;
totalAngle += Angle(points[i], points[j], points[k]);
}
var planarTotalAngle = (points.length - 2) * 180.0;
var sphericalExcess = totalAngle - planarTotalAngle;
if (sphericalExcess > 420.0) {
totalAngle = points.length * 360.0 - totalAngle;
sphericalExcess = totalAngle - planarTotalAngle;
} else if (sphericalExcess > 300.0 && sphericalExcess < 420.0) {
sphericalExcess = Math.abs(360.0 - sphericalExcess);
}
}

/*角度*/
function Angle(p1, p2, p3) {
var bearing21 = Bearing(p2, p1);
var bearing23 = Bearing(p2, p3);
var angle = bearing21 - bearing23;
if (angle < 0) {
angle += 360;
}
return angle;
}

/*方向*/
function Bearing(from, to) {
var lat1 = from[1] * radiansPerDegree;
var lon1 = from[0] * radiansPerDegree;
var lat2 = to[1] * radiansPerDegree;
var lon2 = to[0] * radiansPerDegree;
var angle = -Math.atan2(Math.sin(lon1 - lon2) * Math.cos(lat2), Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2));
if (angle < 0) {
angle += Math.PI * 2.0;
}
return angle;
}

/*平面多边形面积*/
function PlanarPolygonAreaMeters2(points) {
var a = 0;
for (var i = 0; i < points.length; ++i) {
var j = (i + 1) % points.length;
var xi = points[i][0] * metersPerDegree * Math.cos(points[i][1] * radiansPerDegree);
var yi = points[i][1] * metersPerDegree;
var xj = points[j][0] * metersPerDegree * Math.cos(points[j][1] * radiansPerDegree);
var yj = points[j][1] * metersPerDegree;
a += xi * yj - xj * yi;
}
return Math.abs(a / 2);
}

</script>

# 有想换工作的同学可以找我内推哦不低于15k（前端，java，测试）

展开全文
qq_44472722 2020-06-30 18:21:30
• 7KB wangjun891101 2011-11-16 12:05:54
• 计算任意多边形面积的Shoelace公式如下 如代码所示，假设poly为任意四边形，四个顶点分别为，则根据Shoelace公式展开面积为。代码中的公式则为，展开相消会发现和Shoelace公式一样。 参考 ...

### 代码

def polygon_area(poly):
"""
compute area of a polygon
:param poly:
:return:
"""
edge = [(poly[1][0] - poly[0][0]) * (poly[1][1] + poly[0][1]),
(poly[2][0] - poly[1][0]) * (poly[2][1] + poly[1][1]),
(poly[3][0] - poly[2][0]) * (poly[3][1] + poly[2][1]),
(poly[0][0] - poly[3][0]) * (poly[0][1] + poly[3][1])]
return np.sum(edge) / 2.

计算任意多边形面积的Shoelace公式如下

如代码所示，假设poly为任意四边形，四个顶点分别为$(x_{1}, y_{1}), (x_{2}, y_{2}), (x_{3}, y_{3}), (x_{4}, y_{4})$，则根据Shoelace公式展开面积为$x_{1}y_{2} - x_{2}y_{1} + x_{2}y_{3} - x_{3}y_{2} + x_{3}y_{4} - x_{4}y_{3} + x_{4}y_{1} - x_{1}y_{4}$。代码中的公式则为$(x_{1}-x_{2})(y_{1}+y_{2})+(x_{2}-x_{3})(y_{2}+y_{3})+(x_{3}-x_{4})(y_{3}+y_{4})+(x_{4}-x_{1})(y_{4}+y_{1})$，展开相消会发现和Shoelace公式一样。

### 参考

https://zhuanlan.zhihu.com/p/110025234

https://blog.csdn.net/fanzonghao/article/details/103260817

https://blog.csdn.net/dbdxwyl/article/details/109548301

展开全文
ooooocj 2021-05-19 12:24:45
• 8KB weixin_38743968 2019-09-18 08:15:53
• 42KB u010491918 2019-05-06 14:01:52
• ## 根据顶点坐标计算任意多边形的面积和周长 c++

面积，利用微积分思想，任意多边形可以分成若干三角形，相加获得多边形面积。注意，如果是凹多边形面积，是需要减的。 周长，即用（x的平方加y的平方）开根号即可获得，累计相加，应注意的是，不要忘记最后一个点...

面积，利用微积分思想，任意多边形可以分成若干三角形，相加获得多边形面积。注意，如果是凹多边形的面积，是需要减的。
周长，即用（x的平方加y的平方）开根号即可获得，累计相加，应注意的是，不要忘记最后一个点与起始点的线段。
附代码：顶点数据x y 输入到1.txt文件中，如10 40

#include <vector>
//#include <opencv2\opencv.hpp>
#include <iostream>
#include<fstream>
#include <string>
#include<iomanip>
using namespace std;
//using namespace cv;
struct Point
{
double x;
double y;
};
static void Examples();
static double getPolygonArea(vector<Point> const& points);
static double getPolygonLength(vector<Point> const& points);

int main()
{
Examples();
system("pause");
return 0;
}
void Examples()
{//从文件读入
ifstream infile;
infile.open("1.txt");
if (!infile) cout << "error" << endl;
double x; double y;
//存入vector数据
vector<Point> points;
Point point;
while (infile >> x >> y)
{
point.x = x;
point.y = y;
points.push_back(point);
cout << setiosflags(ios::fixed) << setprecision(6) <<"x=" << point.x << "  y=" << point.y<<endl;
}
//计算面积
double area = getPolygonArea(points);
cout << setiosflags(ios::fixed) << setprecision(6) << "Polygon Area = " << area << endl;
//计算周长
double length = getPolygonLength(points);
cout << setiosflags(ios::fixed) << setprecision(6) << "length=" << length << endl;
}
double getPolygonArea(vector<Point> const& points)
{
const int sizep = points.size();
if (sizep < 3)	return 0.0;

double area = points.back().x * points[0].y - points[0].x * points.back().y;
for (int i = 1, j = 0; i < sizep; i++,j++) {
area += (points[j].x * points[i].y);
area -= (points[i].x * points[j].y);
}

return fabs(0.5 * area);
}
double  getPolygonLength(vector<Point> const& points)
{
const int sizep = points.size();
if (sizep < 3)	return 0.0;
double length = sqrt(pow((points.back().x - points[0].x), 2) + pow((points.back().y - points[0].y), 2));

for (int i = 0; i < sizep - 1; i++)
{
length += sqrt(pow((points[i].x - points[i + 1].x), 2) + pow((points[i].y - points[i + 1].y), 2));
}
return length;
}

展开全文
qq_33638170 2020-02-26 20:56:21
• 之前尝试过很多的任意多边形面积计算，都有不同的局限性，直到使用了这个公式后，问题就解决了，感谢原作者的分享。//堰槽坐标定义typedefstruct{doublex;doubley;}WeirCoorType;//任意多边形面积计算doubleCLASS_...

之前尝试过很多的任意多边形截面积计算，都有不同的局限性，直到使用了这个公式后，问题就解决了，感谢原作者的分享。

//堰槽坐标定义

typedef struct

{

double x;

double y;

}WeirCoorType;

//任意多边形面积计算

double CLASS_NAME::PolygonAreaCalculation(WeirCoorType *pWeirCoor, WORD CoorCnt)

{

double sum0 = 0;

double square;

//这个多边形计算代码如此简单，可以计算任意的多边形，就算是弧形都行，只要你输入坐标点就行

for (int i = 0; i

{

sum0 += (pWeirCoor[i].x * pWeirCoor[i + 1].y - pWeirCoor[i + 1].x * pWeirCoor[i].y);

}

square = (fabs(sum0 + (pWeirCoor[CoorCnt - 1].x * pWeirCoor[0].y) - (pWeirCoor[0].x * pWeirCoor[CoorCnt - 1].y))) / 2;

return square;

}

最后测试生成的效果，用于对一个任意河道的不同过水断面进行计算，这个断面就是一个任意多边形。

代码的核心就是计算多边形面积，以及寻找水位线与断面(多边形)的交点，根据交点获取水位以下河道多边形的坐标。

这个绿线对应的就是水位与河道形成的多边形，这个公式可以允许2个相连接的多边形，比如上图所示的，水位Y值为15，灰色区域就是河道，没有水的地方，这个多边形计算公式会自动的计算左右2个过水断面的面积。//计算交点的X值

double CLASS_NAME::CalculateIntersectionX(WeirCoorType *pWeirCoor1, WeirCoorType *pWeirCoor2, double y)

{

double ftemp;

WeirCoorType *pMaxCoor, *pMinCoor;

if (pWeirCoor1->y == pWeirCoor2->y) //Y轴一样，不允许的，随便输出一个X轴

{

SYS_LOG.Write(__FILE__ + __LINE__ + " t：不允许2个坐标的Y轴一样rn");

return pWeirCoor1->x;

}

else if (pWeirCoor1->y > pWeirCoor2->y)

{

pMaxCoor = pWeirCoor1;//Y轴大的点

pMinCoor = pWeirCoor2;//Y轴小的点

}

else

{

pMaxCoor = pWeirCoor2;//Y轴大的点

pMinCoor = pWeirCoor1;//Y轴小的点

}

if (y >= pMaxCoor->y) return pMaxCoor->x;//大于大的点

if (y y) return pMinCoor->x;//小于小的点

//斜线，并且处于中间

ftemp = ((pMaxCoor->y - y) * (pMaxCoor->x - pMinCoor->x)) / (pMaxCoor->y - pMinCoor->y);

ftemp = pMaxCoor->x - ftemp;

return ftemp;

}

这个函数用于计算水位(一个水平横线)与河道交叉点的X坐标，由于水位是一个Y值，X值就是距离河道边零点的距离，通过这个就可以知道水位与河道的交叉点坐标，也就是水位与河道形成的过水断面多边形的交差坐标。

通过下面的这个线程就可以不听的计算任意水位对应的过水断面面积，我的做法是人为设置一个分辨率，比如1cm，程序会计算0cm断面面积，1cm水位断面面积，2cm水位断面面积，依次类推。//线程-运行核心

System::Void CLASS_NAME::BackgroundWorker_DoWork(System::Object^  sender, System::ComponentModel::DoWorkEventArgs^  e)

{

double ftemp;

double Y_Inc = 0.1;//Y轴增量

WORD i;

double X;

int Status;

WORD count;

WORD StartIndex;

int n;

char buff[32];

WeirCoorType TempWeirCoor1[256];

try

{

this->VarY = 0;

for (n = 0; n

{

//WeirCoorType WeirCoor1[9] = { {0,0}, {25,0}, {25,50}, {75,50},{75,0}, {90,0},{100,0}, {100,100},{0,100}};

//坐标必须按照顺序，从左上角，左下角，右下角，右上角顺序，X轴依次增加，左上角与右上角Y轴相等并且最大

//WeirCoorType WeirCoor1[9] = { { 0, 100 }, { 0, 0 }, { 25, 0 }, { 25, 50 }, { 75, 50 }, { 75, 0 }, { 100, 0 }, { 100, 100 }};

//寻找Y轴交点坐标

i = 0;

count = 0;

for (int j = 0; j WeirCoorNum / 2; j++)//循环寻找交点-一对

{

//从第一个坐标开始，先寻找Y值对应的X坐标

for (; i WeirCoorNum - 1); i++)

{

if (this->pWeirCoorBuff[i].y >= this->VarY && this->pWeirCoorBuff[i + 1].y VarY) //左边交点

{

USER_DEBUG.Printf("左交点：%f,%f~%f,%frn", this->pWeirCoorBuff[i].x, this->pWeirCoorBuff[i].y, this->pWeirCoorBuff[i + 1].x, this->pWeirCoorBuff[i + 1].y);

//计算交点坐标

X = this->CalculateIntersectionX(&this->pWeirCoorBuff[i], &this->pWeirCoorBuff[i + 1], this->VarY);

USER_DEBUG.Printf("左交点：(%f,%f)rn", X, this->VarY);

TempWeirCoor1[count].x = X;

TempWeirCoor1[count].y = this->VarY;

count++;

StartIndex = i + 1;

break;

}

}

//从第一个坐标开始，先寻找Y值对应的X坐标

for (; i WeirCoorNum - 1); i++)

{

if (this->pWeirCoorBuff[i].y VarY && this->pWeirCoorBuff[i + 1].y >= this->VarY) //右边交点

{

USER_DEBUG.Printf("右交点：%f,%f~%f,%frn", this->pWeirCoorBuff[i].x, this->pWeirCoorBuff[i].y, this->pWeirCoorBuff[i + 1].x, this->pWeirCoorBuff[i + 1].y);

//计算交点坐标

X = this->CalculateIntersectionX(&this->pWeirCoorBuff[i], &this->pWeirCoorBuff[i + 1], this->VarY);

USER_DEBUG.Printf("右交点：(%f,%f)rn", X, this->VarY);

for (int k = StartIndex; k pWeirCoorBuff[k].x;

TempWeirCoor1[count].y = this->pWeirCoorBuff[k].y;

count++;

}

TempWeirCoor1[count].x = X;

TempWeirCoor1[count].y = this->VarY;

count++;

break;

}

}

if (i >= this->WeirCoorNum - 1) break;

}

this->SelectCoorCount = count;  //选择的点数量

memcpy(this->pSelectWeirCoor1, TempWeirCoor1, sizeof(WeirCoorType) * count);

this->mBackgroundWorker->ReportProgress(1);//状态改变

//打印最终的坐标

USER_DEBUG.Printf("多边形坐标：");

for (i = 0; i

{

USER_DEBUG.Printf("%f,%f t", TempWeirCoor1[i].x, TempWeirCoor1[i].y);

}

USER_DEBUG.Printf("rn");

//WeirCoorType WeirCoor1[8] = { {0,0}, {100,0}, {100,100},{1,100}};

//任意多边形面积计算

ftemp = this->PolygonAreaCalculation(TempWeirCoor1, count);

USER_DEBUG.Printf("面积：%frn", ftemp);

this->SectionalArea = ftemp;//最终的截面积

this->SectionalAreaBuff[n] = this->SectionalArea; //截面积写入全局缓冲区中

this->VarY += this->VerticalResVal;

if (this->VarY > this->pWeirCoorBuff[0].y)

{

USER_DEBUG.Printf("垂直高度超出范围了，退出！rn");

break;

}

Sleep(20);

}

ftemp = this->SectionalArea;

for (; n

{

this->SectionalAreaBuff[n] = ftemp;

ftemp += 0.00001; //截面积只能增大，不能不变，有效位数5位小数自增

}

//生成datatable

this->mDataTable->Rows->Clear();//清空行

for (int i = 0; i

{

DataRow ^dr = this->mDataTable->NewRow();//新建行

sprintf_s(buff, 31, "%.5f", this->SectionalAreaBuff[i]);

dr[0] = CharToString(buff);

}

}

catch (Exception ^e1)

{

SYS_LOG.Write(__FILE__ + __LINE__ + "t:" + e1->Message + e1->StackTrace);

}

}

展开全文
weixin_39673972 2020-12-21 08:12:27
• weixin_39918145 2020-12-21 08:10:28
• cjtlp2006 2017-08-04 10:23:33
• ## vue+d3.js计算任意多边形面积 计算任意多边形面积

qq_42683219 2019-11-25 12:52:12
• ## c++如何求任意多边形的面积 c++

qq_31839479 2016-11-09 19:26:36
• weixin_39863631 2020-12-21 08:10:26
• dixin2013 2020-01-08 16:17:19
• ## python计算任意多边形面积 python 多边形

u012939880 2019-03-05 18:02:57
• ## js根据经纬度计算多边形面积 百度地图 面积 算法 js 多边形面积计算

wennjie1 2017-06-20 10:46:03
• sfw673306004 2020-01-02 12:03:01
• liyuanbhu 2016-07-15 21:20:01
• weixin_30673611 2018-08-22 03:51:00
• ## 计算多边形（polygon）面积的算法原理和python实现 python 多边形面积 polygon

ywcpig 2020-11-12 13:42:58
• Zhudonggangg 2017-04-20 16:12:55
• clz16251102113 2018-09-24 12:38:40
• ## OpenCV 获取区域面积 OpenCV C++

15.23MB weixin_42789529 2019-03-22 09:15:16
• weixin_42676876 2021-01-12 05:18:39
• ## 【几何】计算任意多边形面积 几何 任意多边形面积

Bob__yuan 2019-09-05 13:58:53
• ## 计算两个多边形的重叠面积 c++ 算法

xuyin1204 2020-08-03 16:44:45
• qq_42424503 2020-12-25 11:47:22
• 4星
277B yuyewuyuconan 2011-07-21 09:39:01
• ## 百度地图测量多边形面积 地图测量面积

4星
14KB qq_31832171 2018-04-03 12:09:32

...