首先明确多边形是由直线和圆弧构成的封闭图形,不封闭的话也可以求解(自动按闭合计算)但是面积就没了实际意义;
计算过程如下:
- 采集多边形顶点和曲线数据;
- 将顶点连接而成的多边形进行三角剖分(剖分前进行坐标去重和共线点位的删除,减少三角数量),三角形可直接通过海伦公式计算面积,当然也可以采用三角函数或向量,看个人意愿吧;
- 将曲线部分端点连接形成异型,姑且称作“广义扇形”吧,面积可以通过–>扇形±圆心和圆弧端点形成的三角形得到;
- 曲线部分特殊处理,由于曲线存在内凹的情况所以在计算过程中就存在计算重复面积的情况,因此对于曲线部分需判断是否属于原多边形,属于则保留,不属于则删除,计算模式如下:
①. 通过计算圆弧曲中坐标是否在端点构成的多边形内来判断,曲中在多边形内部则曲线构成的广义扇形不属于原多边形,反之则属于;
②. 通过计算圆弧端点的中点是否在原多边形内来判断,在原多边形内部则曲线构成的广义扇形属于原多边形,反之则不属于;
对于点是否在多边形内,网上有很多方法,我采用了 AcDbMPolygon 的 isPointInsideMPolygon() 方法计算,如下:
#pragma comment(lib, "AcMPolygonObj.lib") // 使用 AcDbMPolygon 记得包含这个库文件
AcGeDoubleArray dulgeArray; // 凸度值可以不写,默认创建由折线形成的包围区域
AcGePoint2dArray ptArray = partitionInfo.m_PtArray;
ptArray.append(ptArray[0]); // 添加第一个点
AcDbMPolygon* pMPolyGon = new AcDbMPolygon();
// 传入的点必须是封闭的,也就是首尾两点要相同,如果不一样可能有些情况计算会错误,无语
if (pMPolyGon && eOk == pMPolyGon->appendMPolygonLoop(ptArray, dulgeArray)) // 也可以使用提供的其他方法,自行选择吧
{
AcGeIntArray loopsArray;
int rt = 0;
for (size_t i = 0; i < partitionInfo.m_PolyArcArray.size(); ++i)
{
loopsArray.removeAll();
// 返回 1说明点在多边形内部,也就是广义扇形不属于原多边形
if (1 == pMPolyGon->isPointInsideMPolygon(AcGePoint3d(partitionInfo.m_PolyArcArray[i].m_PtOnArc.x, partitionInfo.m_PolyArcArray[i].m_PtOnArc.y, 0), loopsArray))
{
partitionInfo.m_PolyArcArray[i].m_IsInner = true;
}
}
}
分解效果如下:
gif上传不了也懒得录视频放弃上传。吐槽一下csdn有点烂啊!
分解对比图:
面积统计说明图: