Boost logo

Geometry :

Subject: Re: [geometry] boost::geometry::touches(point, box) does not compile
From: Brook Milligan (brook_at_[hidden])
Date: 2019-01-22 07:36:32


Dear Adam,

> On Jan 8, 2019, at 11:46 PM, Adam Wulkiewicz <adam.wulkiewicz_at_[hidden]> wrote:
>
> Brook Milligan Via Geometry wrote:
>> I am curious why the following code does not compile.
>>
>> #include <boost/geometry/algorithms/touches.hpp>
>> #include <boost/geometry/geometries/box.hpp>
>> #include <boost/geometry/geometries/point_xy.hpp>
>>
>> int main ()
>> {
>> using point_type = boost::geometry::model::d2::point_xy<int>;
>> using box_type = boost::geometry::model::box<point_type>;
>>
>> point_type point { 0,0 };
>> box_type box { {0,0},{1,1} };
>> boost::geometry::touches(point,box);
>> }
>>
>> It seems that touches() is not implemented for a point and a box, although it would seem to be simple to implement.
>>
> It might be unintentional however I could think of a reason. The main reason may be that Box is not defined by the OGC standard used in Boost.Geometry. To be more precise:
>
> It's not clear what is a valid box. Consider e.g. when Box degenerates to a segment or point (e.g. box{{0,0},{0,0}}) typically this would be considered valid because it might be a non-enlarged bounding box of a point. On the other hand if we represented it as polygon it would be invalid because it has area = 0. Now considering that relational operations in Boost.Geometry are defiend by DE9IM model (https://en.wikipedia.org/wiki/DE-9IM), should we treat this degenerated box as point (it'd have only the interior and no boundary) or as some kind of degenerated areal geometry (only boundary but no interior) or maybe some wierd hybrid (both interior and boundary at the same point)? In either of these cases the result of touches(point, box) would be different and in the last case ambiguous. So this function might have been ommited because it wasn't clear what should be the result and to just deal with it in the future if someone really needs it.
>
> Another issue is that since bounding boxes are used for indexing and are not OGC-geometries we may treat them differently than the other geometries when the speed is important. E.g. relational operations for boxes does not check equality of coordinates using machine epsilon. This means that touches(point, box) and touches(point, polygon) could return different result for cases like this:
>
> touches(point{0-eps/2, 0}, box{{0,0},{1,1}});
> touches(point{0-eps/2, 0}, polygon{{{0,0},{0,1},{1,1},{1,0},{0,0}}});
>
> This is a lesser problem (sort of) because intersects() or covered_by() probably already returns different results. The first case would probably use strict coordinates comparison without epsilon and my guess is that someone might think that it wouldn't be that useful. Boxes are used as bounding objects of other geometries and I cannot think of a use for finding out it a point touches a bounding box of some geometry. Unless a box is not used as bounding object but then the way how the coordinates are compared could depend on the specific use case.
>
> Are you in need of this or asking out of curiosity?
> What would you like to use it for?

Thanks for the thoughtful explanation. I suppose I didn't really think of all the implications and you raise some very good points.

When I wrote my inquiry, I did need it to make some user-code work well, but in the meantime I have figured out a different solution that in fact does not require it. So, I suppose in the end I don't need it after all. In any case, I wasn't really asking out of pure curiosity, but rather was motivated by a potential use case.

I think this raises another issue that is more pervasive in Boost.Geometry, though. That is the difficulty with providing user-defined strategies. It seems to me that the strategy mechanism is really hard to grok; for example, as far as I know, there is no documentation on what concepts a strategy must model. Consequently, I have never been able to figure out how to provide my own strategy for anything. If this were more straightforward, then all of the approaches you have mentioned above (and more) could be supported, either by the library providing appropriate strategies or by making a default decision that can be overridden by users with their own strategies. I point this out, because it seems to me that none of the *_with_strategy functions are useful for an end-user without some documentation on what a strategy is required to provide. I realize this is a much bigger issue than my initial question, but I want to point it out in case there can be some progress in this area.

Thanks for your work on the library.

Cheers,
Brook


Geometry list run by mateusz at loskot.net