地球椭球面上多边形面积量算(C++代码)

昨天突然测试的时候发现以前产品中写的地球椭球面上面积计算的代码有点问题,于是今天就彻底修正,从QGIS中抠出代码来用C++重写了一下,新代码可以比较准确计算椭球面上多边形的面积,这个基础函数对空间量算功能中的面积量测非常重要,在这里共享出来供大家参考甚至直接拿过去用。

头文件如下:

/**
* @file              DistanceArea.h
* @brief             椭球面上计算多边形面积的接口文件
* @details
* @author            zxg
* @date              2015年5月15日
* @version           1.0.0.1
* @par               Copyright (c):周旭光
* @par               History:
*/
#ifndef __DISTANCEAREA_H_C0C6C4C8_B1C4_49C3_87E4_EEF1ABC862F0__
#define __DISTANCEAREA_H_C0C6C4C8_B1C4_49C3_87E4_EEF1ABC862F0__

class DistanceArea
{
public:
	DistanceArea();

    ~DistanceArea();

	/**
	* @brief SetEllipsePara 设置计算面积的参数
	* @param[in] double a 长半轴
	* @param[in] double b 短半轴
	* @return void
	* @author zxg
	* @date 2015年5月15日
	* @note
	*/
	void SetEllipsePara(double a,double b);

	/**
	* @brief ComputePolygonArea 计算地球椭球面上多边形的面积
	* @param[in]  const double *padX X坐标数组
	* @param[in] const double* padY Y坐标数组
	* @param[in] int nCount 点的个数
	* @return double 返回值是面积
	* @author zxg
	* @date 2015年5月15日
	* @note
	*/
	double ComputePolygonArea( const double *padX,const double* padY,int nCount );

private:

    double mSemiMajor, mSemiMinor, mInvFlattening;

    double GetQ( double x );
    double GetQbar( double x );

	void ComputeAreaInit();

    // 面积计算临时变量

    double m_QA, m_QB, m_QC;
    double m_QbarA, m_QbarB, m_QbarC, m_QbarD;
    double m_AE;  /* a^2(1-e^2) */
    double m_Qp;
    double m_E;
    double m_TwoPI;

};

#endif // end of __DISTANCEAREA_H_C0C6C4C8_B1C4_49C3_87E4_EEF1ABC862F0__

实现代码如下:

#include "DistanceArea.h"

#define DEG2RAD(x)    ((x)*M_PI/180)

DistanceArea::DistanceArea()
{
	//
}

DistanceArea::~DistanceArea()
{
}

void DistanceArea::SetEllipsePara(double a,double b)
{
	mSemiMajor = a;
	mSemiMinor = b;
	//mInvFlattening = mSemiMajor

	ComputeAreaInit();
}

double DistanceArea::GetQ( double x )
{
	double sinx, sinx2;

	sinx = sin( x );
	sinx2 = sinx * sinx;

	return sinx *( 1 + sinx2 *( m_QA + sinx2 *( m_QB + sinx2 * m_QC ) ) );
}

double DistanceArea::GetQbar( double x )
{
	double cosx, cosx2;

	cosx = cos( x );
	cosx2 = cosx * cosx;

	return cosx *( m_QbarA + cosx2 *( m_QbarB + cosx2 *( m_QbarC + cosx2 * m_QbarD ) ) );
}

void DistanceArea::ComputeAreaInit()
{
	double a2 = ( mSemiMajor * mSemiMajor );
	double e2 = 1 - ( a2 / ( mSemiMinor * mSemiMinor ) );
	double e4, e6;

	m_TwoPI = M_PI + M_PI;

	e4 = e2 * e2;
	e6 = e4 * e2;

	m_AE = a2 * ( 1 - e2 );

	m_QA = ( 2.0 / 3.0 ) * e2;
	m_QB = ( 3.0 / 5.0 ) * e4;
	m_QC = ( 4.0 / 7.0 ) * e6;

	m_QbarA = -1.0 - ( 2.0 / 3.0 ) * e2 - ( 3.0 / 5.0 ) * e4  - ( 4.0 / 7.0 ) * e6;
	m_QbarB = ( 2.0 / 9.0 ) * e2 + ( 2.0 / 5.0 ) * e4  + ( 4.0 / 7.0 ) * e6;
	m_QbarC =                     - ( 3.0 / 25.0 ) * e4 - ( 12.0 / 35.0 ) * e6;
	m_QbarD = ( 4.0 / 49.0 ) * e6;

	m_Qp = GetQ( M_PI / 2 );
	m_E  = 4 * M_PI * m_Qp * m_AE;
	if ( m_E < 0.0 )
	m_E = -m_E;
}

double DistanceArea::ComputePolygonArea( const double *padX,const double* padY,int nCount )
{
	double x1, y1, dx, dy;
	double Qbar1, Qbar2;

	if (NULL == padX || NULL == padY)
	{
		return 0;
	}

	if (nCount < 3)
	{
		return 0;
	}

	double x2 = DEG2RAD( padX[nCount-1] );
	double y2 = DEG2RAD( padY[nCount-1] );
	Qbar2 = GetQbar( y2 );

	double area = 0.0;

	for ( int i = 0; i < nCount; i++ )
	{
		x1 = x2;
		y1 = y2;
		Qbar1 = Qbar2;

		x2 = DEG2RAD( padX[i] );
		y2 = DEG2RAD( padY[i] );
		Qbar2 = GetQbar( y2 );

		if ( x1 > x2 )
		  while ( x1 - x2 > M_PI )
			x2 += m_TwoPI;
		else if ( x2 > x1 )
		  while ( x2 - x1 > M_PI )
			x1 += m_TwoPI;

		dx = x2 - x1;
		area += dx * ( m_Qp - GetQ( y2 ) );

		if (( dy = y2 - y1 ) != 0.0 )
		  area += dx * GetQ( y2 ) - ( dx / dy ) * ( Qbar2 - Qbar1 );
	}
	if (( area *= m_AE ) < 0.0 )
		area = -area;

	if ( area > m_E )
		area = m_E;
	if ( area > m_E / 2 )
		area = m_E - area;

	return area;
}

主要的函数是ComputePolygonArea,计算出来的面积单位是平方米。

测试示例如下:

std::vector<double> vecX;
	std::vector<double> vecY;
	vecX.push_back(116.0120);
	vecX.push_back(116.0121);
	vecX.push_back(116.01205);

	vecY.push_back(40.004);
	vecY.push_back(40.004);
	vecY.push_back(40.0041);

	DistanceArea area;
	area.SetEllipsePara(6378140.0,6356755.0);
	double aaa = area.ComputePolygonArea(&vecX[0],&vecY[0],vecY.size());

经过测试,可以满足要求。

时间: 2024-10-08 08:56:35

地球椭球面上多边形面积量算(C++代码)的相关文章

HDU 3060 多边形面积并

Area2 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1197    Accepted Submission(s): 278 Problem Description 小白近期又被空军特招为飞行员,參与一项实战演习.演习的内容还是轰炸某个岛屿(这次的岛屿非常大,非常大非常大非常大,大到炸弹怎么扔都能全然在岛屿上引爆),看来小白确实是

Area - POJ 1654(求多边形面积)

题目大意:从原点开始,1-4分别代表,向右下走,向右走,向右上走,向下走,5代表回到原点,6-9代表,向上走,向左下走,向左走,向左上走.求出最后的多边形面积. 分析:这个多边形面积很明显是不规则的,可以使用向量积直接求出来面积即可. 代码如下: ------------------------------------------------------------------------------------------------------------------------------

HDU 3982 半平面交+圆与多边形面积交

Harry Potter and J.K.Rowling Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 685    Accepted Submission(s): 210 Problem Description In July 31st, last month, the author of the famous novel seri

改革春风吹满地(多边形面积)

http://acm.hdu.edu.cn/showproblem.php?pid=2036 改革春风吹满地 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 22973    Accepted Submission(s): 11889 Problem Description “ 改革春风吹满地,不会AC没关系;实在不行回老家,还有一亩三分

多边形面积的求法

学了高数的同学,会学到向量的外积,也可知道它有一个用途,可以求三角面积. •外积的几何意义:α和β所张成的平行四边形的有向面积 •由求三角形面积的方法可以推广求凸多边形面积,如图,从一固定点出发,向其他各点引辅助线,这样就分割成了若干个三角形,利用上式求出每个三角形的面积再相加即可. 代码实现: 不过这种方法有局限性,只能求凸多边形的面积,对于凹多边形似乎就不可以了. 这里再提供一种凸凹都合适的求法,不过我也不太懂,如果哪位大神看到了,就不吝赐教一下,现在这里谢过了. •double Area(

eoj1127 计算几何 任意多边形面积

题目:eoj1127 " 改革春风吹满地, 不会算法没关系; 实在不行回老家, 还有一亩三分地. 谢谢!(乐队奏乐)" 话说部分学生心态极好,每天就知道游戏,这次考试如此简单的题目,也是云里雾里,而且,还竟然来这么几句打油诗. 好呀,老师的责任就是帮你解决问题,既然想种田,那就分你一块. 这是一块多边形形状的田,原本是Partychen的,现在就准备送给你了.不过,任何事情都没有那么简单,你必须首先告诉我这块地到底有多少面积,如果回答正确才能真正得到这块地. 发愁了吧?就是要让你知道,

凸包 及 多边形面积

首先求多边形面积,这个比较简单,用的就是把一个多边形划分为多个三角形,然后求三角形面积. 代码: double Cross(Vector A,Vector B) { return (A.x*B.y-A.y*B.x); } double ConvexPolygonArea(Point* p,int n)//多边形面积,,点按顺序 { double area=0; for(int i=1;i<n-1;i++) area+=Cross(p[i]-p[0],p[i+1]-p[0]); return ar

多边形面积

多边形面积 多边形通常分为凸多边形和凹多边形 计算多边形面积有几种好用的算法 其核心思想都是把一个n(n>=3)边形转化为n-2个三角形,然后计算 一:海伦公式 最常见的多边形面积计算公式 此公式表达式为: S= sqrt( p*(p-a)*(p-b)*(p-c)) 其中p为此三角形的半周长,而a,b,c为三角形三边长 若三角形三点为x1,y1,x2,y2,x3,y3, 即p=(a+b+c)/2 a=sqrt((x2-x1)2+(y2-y1)2) b=sqrt((x3-x2)2+(y3-y2)2

EOJ 1058. 挤模具 (多边形面积)

题目链接:1058. 挤模具 题意 给出模具的底和体积,求模具的高. 思路 模具的底为多边形,因此求出多边形面积,用体积除以底的面积就是答案. 多边形的面积求解见 EOJ 1127. 多边形面积(计算几何) 代码 #include <cstdio> #include <iostream> #include <vector> #include <cmath> #include <algorithm> using namespace std; typ