我試圖使用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,謝謝你的迴應。我已經相應地更新了這篇文章。 –