Subject: [Boost-bugs] [Boost C++ Libraries] #10772: boost::geometry::within() does not recognize empty boxes
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2014-11-08 19:04:31
#10772: boost::geometry::within() does not recognize empty boxes
------------------------------+---------------------------
Reporter: bromeon@⦠| Owner: barendgehrels
Type: Bugs | Status: new
Milestone: To Be Determined | Component: geometry
Version: Boost 1.57.0 | Severity: Problem
Keywords: |
------------------------------+---------------------------
If boost::geometry::within() is used to check whether an empty box (i.e. a
point) is within another box, false is always returned. This is not the
correct behavior because:
1. OGC defines: a.Within(b) â (aâ©b=a) ⧠(I(a)â©E(b)=â
) which holds true.
The intersection of an empty box ''a'' and a surrounding box ''b'' yields
''a''. Since ''a'' has no interior, I(a)=â
, thus the second condition is
also true.
2. Empty boxes should be treated as points. When using a point model
instead of an empty box, the check returns the correct result as expected.
See also the following complete minimal code (it includes also other
geometry algorithms that are computed consistently for points and empty
boxes):
{{{
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/algorithms/within.hpp>
#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/intersects.hpp>
#include <boost/geometry/algorithms/disjoint.hpp>
#include <boost/geometry/algorithms/distance.hpp> // needed for within()
-- is this intended?
#include <iostream>
namespace bg = boost::geometry;
typedef bg::model::d2::point_xy<float> Point;
typedef bg::model::box<Point> Box;
int main()
{
Point point(3, 4);
Box pointAsBox;
bg::convert(point, pointAsBox);
Box surrounding;
surrounding.min_corner() = Point(2, 2);
surrounding.max_corner() = Point(5, 5);
std::cout << " Point Box" << std::endl;
std::cout << "within: " << bg::within(point, surrounding)
<< " " << bg::within(pointAsBox, surrounding)
<< "\n"; // 1 0 <-
std::cout << "within (self): " << bg::within(point, point)
<< " " << bg::within(pointAsBox, pointAsBox)
<< "\n"; // 1 0 <-
std::cout << "covered_by: " << bg::covered_by(point,
surrounding)
<< " " << bg::covered_by(pointAsBox,
surrounding) << "\n"; // 1 1
std::cout << "intersects: " << bg::intersects(point,
surrounding)
<< " " << bg::intersects(pointAsBox,
surrounding) << "\n"; // 1 1
std::cout << "disjoint: " << bg::disjoint(point,
surrounding)
<< " " << bg::disjoint(pointAsBox,
surrounding) << "\n"; // 0 0
std::cout << std::endl;
}
}}}
The implementation looks as follows
(boost/geometry/strategies/cartesian/box_in_box.hpp, line 32):
{{{
struct box_within_range
{
template <typename BoxContainedValue, typename BoxContainingValue>
static inline bool apply(BoxContainedValue const& bed_min
, BoxContainedValue const& bed_max
, BoxContainingValue const& bing_min
, BoxContainingValue const& bing_max)
{
return bing_min <= bed_min && bed_max <= bing_max // contained in
containing
&& bed_min < bed_max; // interiors
overlap
}
};
}}}
The problem is the second line, which uses < and thus returns false if the
coordinates are equal. I'm not sure what the intention is (despite the
comment), and whether it is needed at all.
The documentation about box model and concept doesn't state whether
max_corner's coordinates must be component-wise greater or equal than
min_corner's. If so, it seems like valid boxes are a precondition to
within() and this line could be removed.
-- Ticket URL: <https://svn.boost.org/trac/boost/ticket/10772> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-02-16 18:50:17 UTC