The output may seem correct the first around, but in fact it isn't if you look closer:
A slightly refactored sample: Live On Coliru
#include <boost/geometry.hpp>
#include <boost/geometry/io/io.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/array.hpp>
#include <vector>
#include <iomanip>
namespace bg = boost::geometry;
template <typename C, typename T = typename C::value_type>
void append(C& container, std::initializer_list<T> init) {
container.insert(container.end(), init);
}
int main() {
typedef bg::model::d2::point_xy<double> TBoostPoint;
typedef bg::model::polygon<TBoostPoint> TBoostPoly;
std::vector<TBoostPoly> squares;
using Eps = boost::array<double, 4>;
for (auto const& eps : {
Eps {{ 0, 0, 0, 0 }},
Eps {{ 1e-15, 1e-15, 2e-15, 2e-15 }},
})
{
TBoostPoly square;
append(square.outer(), {
{ 0.5, 4.25 + eps[0] },
{ 0.5, 4.5 + eps[1] },
{ 1.0, 4.5 + eps[2] },
{ 1.0, 4.25 + eps[3] },
{ 0.5, 4.25 + eps[0] }
});
squares.push_back(std::move(square));
}
for (auto& p : squares)
bg::correct(p);
std::vector<TBoostPoly> output;
bg::intersection(squares[0], squares[1], output);
for (auto& p : output) std::cout << "Output: " << bg::wkt(p) << "\n";
std::cout << std::fixed << std::setprecision(std::numeric_limits<bg::coordinate_type<TBoostPoint>::type >::max_digits10);
for (auto& p : output) std::cout << "Output: " << bg::wkt(p) << "\n";
}
Which prints
Output: POLYGON((0.5 4.5,1 4.5,1 4.25,0.5 4.25,0.5 4.5))
Output: POLYGON((0.50000000000000000 4.50000000000000000,1.00000000000000000 4.50000000000000000,1.00000000000000000 4.25000000000000178,0.50000000000000000 4.25000004999999970,0.50000000000000000 4.50000000000000000))
As you can see, the naive, natural output may seem to be 4.25
at some point, but the actual value stored is 4.25000000000000178
at that exact moment.
Depending on what requirements you have you might be happier with some arbitrary precision decimal representation types. As a proof of concept, here's the same program parameterized to use 50-digit decimal floats:
Live On Coliru
#include <boost/geometry.hpp>
#include <boost/geometry/io/io.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/array.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <vector>
#include <iomanip>
namespace bg = boost::geometry;
namespace bmp = boost::multiprecision;
template <typename C, typename T = typename C::value_type>
void append(C& container, std::initializer_list<T> init) {
container.insert(container.end(), init);
}
int main() {
typedef bmp::number<bmp::cpp_dec_float<50>, bmp::et_off> Decimal;
typedef bg::model::d2::point_xy<Decimal> TBoostPoint;
typedef bg::model::polygon<TBoostPoint> TBoostPoly;
std::vector<TBoostPoly> squares;
using Eps = boost::array<Decimal, 4>;
for (auto const& eps : {
Eps {{ 0, 0, 0, 0 }},
Eps {{ 1e-15, 1e-15, 2e-15, 2e-15 }},
})
{
TBoostPoly square;
append(square.outer(), {
{ 0.5, 4.25 + eps[0] },
{ 0.5, 4.5 + eps[1] },
{ 1.0, 4.5 + eps[2] },
{ 1.0, 4.25 + eps[3] },
{ 0.5, 4.25 + eps[0] }
});
squares.push_back(std::move(square));
}
for (auto& p : squares)
bg::correct(p);
std::vector<TBoostPoly> output;
bg::intersection(squares[0], squares[1], output);
for (auto& p : output) std::cout << "Output: " << bg::wkt(p) << "\n";
std::cout << std::fixed << std::setprecision(std::numeric_limits<bg::coordinate_type<TBoostPoint>::type >::max_digits10);
for (auto& p : output) std::cout << "Output: " << bg::wkt(p) << "\n";
}
Which prints:
Output: POLYGON((0.5 4.5,1 4.5,1 4.25,0.5 4.25,0.5 4.5))
Output: POLYGON((0.50000000000000000000000000000000000000000000000000000000000000000000000000000000 4.50000000000000000000000000000000000000000000000000000000000000000000000000000000,1.00000000000000000000000000000000000000000000000000000000000000000000000000000000 4.50000000000000000000000000000000000000000000000000000000000000000000000000000000,1.00000000000000000000000000000000000000000000000000000000000000000000000000000000 4.25000000000000200000000000000015541079975332215847661437120239003029098500000000,0.50000000000000000000000000000000000000000000000000000000000000000000000000000000 4.25000000000000100000000000000007770539987666107923830718560119501514549200000000,0.50000000000000000000000000000000000000000000000000000000000000000000000000000000 4.50000000000000000000000000000000000000000000000000000000000000000000000000000000))