I'm trying to judge whether / how I can make Boost.Geometry work for a particular use case. I cannot, however, find documentation about how the library deals with floating point types anywhere.
If you search the official documentation for the word "epsilon" you get zero hits as far as I can tell; however, it is clear from the library's behavior that it is implicitly using some version of the typical way one deals with floats when making comparisons because, for example, the union_ operation will union two polygons that are near each other but not overlapping if they are near enough.
Consider for example the following code which performs a binary search to determine the threshold distance that two unit squares need to be within to be considered adjacent when union-ing:
namespace bg = boost::geometry;
using point = bg::model::d2::point_xy<double>;
using polygon = bg::model::polygon<point, false>;
polygon create_poly(std::vector<std::tuple<double, double>> pts) {
polygon poly;
for (const auto& [x, y] : pts)
bg::append(poly, bg::make<point>(x, y));
auto [x_1, y_1] = pts[0];
bg::append(poly, bg::make<point>(x_1, y_1));
return poly;
}
bool perform_simple_union(const polygon& p1, const polygon& p2) {
std::vector<polygon> output;
bg::union_(p1, p2, output);
return output.size() == 1;
}
double find_epsilon(double left, double right) {
if (right - left < std::numeric_limits<double>::epsilon())
return left;
double eps = (left + right) / 2;
polygon a = create_poly(
std::vector<std::tuple<double, double>>{
{1.0, 1.0}, { 2.0,1.0 }, { 2.0, 2.0 }, { 1.0,2.0 }
}
);
polygon b = create_poly(
std::vector<std::tuple<double, double>>{
{2.0 + eps, 1.0}, { 3.0 + eps, 1.0 }, { 3.0 + eps, 2.0 }, { 2.0 + eps,2.0 }
}
);
if ( perform_simple_union(a, b) ) {
return find_epsilon(eps, right);
} else {
return find_epsilon(left, eps);
}
}
int main()
{
auto eps = find_epsilon(0.0, 1.0);
std::cout << "eps == " << eps << "\n";
}
when I compile and run the above with Visual Studio I get the output
eps == 1e-07
which is about the numeric limits epsilon of single precision floats. So it's treating double precision coordinates as if they are equivalent if they are within single precision epsilon from each other?
Basically I'd just like to know what the default behavior is so I can decide if it works for me.