C++ 使用GPC或裁剪器计算多边形相交面积
我有一个二维粒子系统,其中粒子表示为椭圆。我需要计算椭圆-椭圆重叠区域,但这是一个很难分析的问题。现在,我将椭圆表示为20个角,因此它们是“多边形化的”,我正在使用C++ 使用GPC或裁剪器计算多边形相交面积,c++,geometry,polygons,boost-geometry,C++,Geometry,Polygons,Boost Geometry,我有一个二维粒子系统,其中粒子表示为椭圆。我需要计算椭圆-椭圆重叠区域,但这是一个很难分析的问题。现在,我将椭圆表示为20个角,因此它们是“多边形化的”,我正在使用Boost.Geometry进行必要的计算 但是,我经常从Boost.Geometry:Boost.Geometry overlay无效输入异常中得到异常。我搜索并发现这是已知的boost.Geometry错误,从版本1.53起没有修复。即使即将发布的v1.54的文档也没有说明如何解决这个问题 我偶然发现并发现了。他们似乎做了我想要的
Boost.Geometry
进行必要的计算
但是,我经常从Boost.Geometry
:Boost.Geometry overlay无效输入异常中得到异常。我搜索并发现这是已知的boost.Geometry
错误,从版本1.53起没有修复。即使即将发布的v1.54的文档也没有说明如何解决这个问题
我偶然发现并发现了。他们似乎做了我想要的,但他们只输出布尔结果。有人知道有没有办法输出这些库的计算交点面积?我想,因为交点作为某种多边形存储在内存中,所以我可以使用三角剖分或其他方法来计算面积。
任何指点都将不胜感激
在Linux Mint 14下的Win7 x64、MinGW和Qt 4.8.1下的MSVC 2010和2012中,Boost overlay的异常是一致的。您可以向Boost票证系统提交票证吗?包括给出无效输入异常的几何体对的示例?该错误可能有多种原因,要么确实无效,要么是库中的错误。其中一些问题根据1.54进行了修复。看来您对Clipper和GPC的看法是错误的,“它们只输出布尔结果”。这两个库都计算相交多边形-例如,请查看Clipper页面上带有图片的代码段。在Angus的Clipper与其他库的基准测试中,他有一种多边形面积计算方法。我用了这个,修改了他的椭圆方法。结果如下:
void Ellipse2Poly(double theta, double A1, double B1, double H1, double K1, Poly& p)
{
const double pi = 3.1415926535898, tolerance = 0.125;
const int n = 30;
double step = pi/(double)n;
double a = A1; // Long semi-axis length
double b = B1; // short semi-axis length
double xc = H1; // current X position
double yc = K1; // current Y position
double sintheta = sin(theta);
double costheta = cos(theta);
double t = 0;
p.resize(2*n+1);
for (int i = 0; i < 2*n+1; i++)
{
p[i].x = xc + a*cos(t)*costheta - b*sin(t)*sintheta;
p[i].y = yc + a*cos(t)*sintheta + b*sin(t)*costheta;
t += step;
}
}
它比Boost.Geometry慢,但非常稳定。我在一夜之间运行了2*10^5个时间步,它没有崩溃。这花了6小时12分钟,而推进大约需要4小时,但我很高兴
编辑:
我已经重写了一些其他函数,所以这个比较对Clipper不公平!对于相同的配置和100K的时间步长,Clipper在2小时36分钟内完成了操作,我觉得这非常好!Boost将在大约2小时15分钟内完成相同的操作,因此我发现它们在这些长时间运行中非常具有可比性 谢谢你的回复!我将提交一张票。这是非常好的听到,这可能是固定在1.54!事实上,你有一部分是对的。在代码片段中,您最终可以看到,对于Clipper
c
对象,Angus使用以下内容:c.Execute(ctIntersection,solution,pftNonZero,pftNonZero)代码>,这是一个布尔表达式。但在他的基准测试中,他正在计算面积,我找到了一种方法来根据我的需要修改他的代码。我会将你的答案标记为正确答案,因为它让我思考,让我走上正确的轨道!谢谢你提到的论文的作者发布了他们算法的实现,为了验证聚合方法(你刚才使用的代码)。分析方法比数值方法快约10倍。你为什么喜欢多边形方法而不是解析解?
double OverlapArea(Poly poly1, Poly poly2)
{
Poly clip;
Polys polys_poly1, polys_poly2, polys_clip;
polys_poly1.resize(1);
polys_poly2.resize(1);
polys_clip.resize(1);
polys_poly1[0] = poly1;
polys_poly2[0] = poly2;
polys_clip[0] = clip;
Polygons clipper_polys_poly1, clipper_polys_poly2, clipper_polys_clip;
LoadClipper(clipper_polys_poly1,polys_poly1);
LoadClipper(clipper_polys_poly2,polys_poly2);
ClipType op = ctIntersection;
Clipper cp;
cp.AddPolygons(clipper_polys_poly1,ptSubject);
cp.AddPolygons(clipper_polys_poly2,ptClip);
cp.Execute(op,clipper_polys_clip,pftEvenOdd,pftEvenOdd);
if(clipper_polys_clip.size() != 0)
{
UnloadClipper(polys_clip,clipper_polys_clip);
return Area(polys_clip[0]);
}
else
return 0.0;
}