我试图使用Boost :: Geometry _union与整数,为性能和数字的准确性。为此,我将输入的坐标乘以10,000。从而创建最多9位数的坐标。我认为,因为我使用64位整数,这应该很好。如何使用Boost :: Geometry _union与整数
不幸的是,当我运行代码时,我得到了奇怪的结果(输出多边形包括一个远离输入中任何多边形的点)。调查升压的代码::几何给我带来了这样的结论:原产地是在文件cart_intersect.hpp一个环绕式的问题:
set<1>(point, get<0, 1>(segment) + boost::numeric_cast
<
CoordinateType
>(numerator * dy_promoted/denominator));
当所有三个(分子,dy_promoted和分母)是巨大的,在乘法的结果需要超过64位,因此整个结果是不正确的。
使用Boost :: Geometry与这样的大整数有效吗?在保持正确性和精确度的同时使用Boost :: Geometry的正确方法是什么?
编辑 @sehe,感谢您的答复。这里是一个SSCCE,编译VS2013和Boost 1.63
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/multi/geometries/multi_polygon.hpp>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
namespace bg = boost::geometry;
typedef bg::model::d2::point_xy<long long, bg::cs::cartesian> TPoint;
typedef bg::model::ring<TPoint> TRing;
typedef bg::model::polygon<TPoint> TPolygon;
typedef bg::model::multi_polygon<TPolygon> TMultiPolygon;
void PrintRing(const TRing& rng)
{
for (const auto& ver : rng)
{
cout << "(" << ver.x() << "," << ver.y() << "),";
}
}
void PrintPolygon(const TPolygon& pol)
{
cout << "Outer: ";
PrintRing(pol.outer());
cout << endl;
for (const auto& rng : pol.inners())
{
cout << "Inner: ";
PrintRing(rng);
cout << endl;
}
}
void PrintMultiPolygon(const string name, const TMultiPolygon& mp)
{
cout << "Multi-Polygon " << name << " : " << endl;
for (const auto& pol : mp)
{
PrintPolygon(pol);
}
cout << endl;
}
int main()
{
cout << "BOOST_LIB_VERSION: " << BOOST_LIB_VERSION << endl;
const vector<TPoint> verticesA{ { -405129, 2010409 }, { 3370580, 2010409 }, { 3370580, 1997709 }, { -405129, 1997709 }, { -405129, 2010409 } };
const TRing rngA(verticesA.cbegin(), verticesA.cend());
TPolygon polA;
polA.outer() = rngA;
TMultiPolygon mpA;
mpA.push_back(polA);
const vector<TPoint> verticesB{ { 3364230, -895349 }, { 3364230, 2004060 }, { 3376930, 2004059 }, { 3376930, -895350 }, { 3364230, -895349 } };
const TRing rngB(verticesB.cbegin(), verticesB.cend());
TPolygon polB;
polB.outer() = rngB;
TMultiPolygon mpB;
mpB.push_back(polB);
TMultiPolygon output;
bg::union_(mpA, mpB, output);
PrintMultiPolygon("A", mpA);
PrintMultiPolygon("B", mpB);
PrintMultiPolygon("output", output);
}
程序的输出:
BOOST_LIB_VERSION: 1_63
Multi-Polygon A :
Outer: (-405129,2010409),(3370580,2010409),(3370580,1997709),(-405129,1997709),(-405129,2010409),
Multi-Polygon B :
Outer: (3364230,-895349),(3364230,2004060),(3376930,2004059),(3376930,-895350),(3364230,-895349),
Multi-Polygon output :
Outer: (3370580,2004060),(3376930,2004059),(3376930,-895350),(3364230,-895349),
(3364230,-1372382)
,(-405129,1997709),(-405129,2010409),(3370580,2010409),(3370580,2004060),
注意以粗体显示的坐标,Y值是远超过任何Y坐标在输入中。
您可以使用整数类型来防止boost :: multiprecision的溢出和/或大容量整数。如果您发布SSCCE,我们可以向您展示一个示例。现在我们不能给出更有用的答案,因为所有有用的代码都缺少问题。 – sehe
@sehe,谢谢你的回应。我已经相应地更新了这篇文章。 –