Boost logo

Geometry :

Subject: Re: [geometry] Geometries represented in multiple point types
From: Andrew Hundt (athundt_at_[hidden])
Date: 2013-01-30 16:05:05


Ok, since there isn't a way for it to work right now I'll go with a
workaround, using one as the default and a wrapper for the other.

Supposing one wanted to implement this sort of functionality perhaps
it could be done using some of these elements, adapted from the
register box example:

struct grid_point_tag : boost::geometry::point_tag {};
struct world_point_tag : boost::geometry::point_tag {};

template<typename T, typename Unique>
struct point {
  typedef T value_type;
  typedef Unique unique_type;
  T x; T y;

  // ...snip... constructor, operator overloads, etc
 };

typedef point<double,world_point_tag> world_point;
typedef point<int,grid_point_tag> grid_point;

// ...snip... code registering the tags to world_point and grid_point

BOOST_GEOMETRY_REGISTER_SYSTEM_POINT_2D(grid_point,
grid_point::value_type, cs::cartesian, grid_point_tag, x, y)

BOOST_GEOMETRY_REGISTER_SYSTEM_POINT_2D(world_point,
world_point::value_type, cs::cartesian, world_point_tag, x, y)

struct DualBox {

  template<Point>
  Point min_corner();

  template<Point>
  Point max_corner();

  // ...snip...

};

BOOST_GEOMETRY_REGISTER_MULTI_SYSTEM_BOX_TEMPLATE( DualBox,
grid_point_tag,min_corner<grid_point>(),max_corner<grid_point>() );

BOOST_GEOMETRY_REGISTER_MULTI_SYSTEM_BOX_TEMPLATE( DualBox,
world_point_tag,min_corner<world_point>(),max_corner<world_point>() );

int main()
{
    // suppose grid_point and world_point match up at 0,0 and have the
same scale
    // this is not guaranteed and generally not true, but simplifies
this example
    DualBox db(grid_point(0,0), grid_point(2,2));
    world_point wpi(1.0,1.0);
    world_point wpo(3.0,3.0);
    grid_point gpi(1,1);
    grid_point gpo(3,3);

    bool wptrue = boost::geometry::within(wpi,db);
    bool wpfalse = boost::geometry::within(wpo,db);
    bool gptrue = boost::geometry::within(gpi,db);
    bool gpfalse = boost::geometry::within(gpo,db);
}

I'm sure there are ways this can be improved but I wanted to mention the idea.

Cheers!
Andrew Hundt

On Wed, Jan 30, 2013 at 12:47 PM, Barend Gehrels <barend_at_[hidden]> wrote:
>
> Hi Andrew,
>
> Welcome to the list.
>
>
> On 30-1-2013 0:48, Andrew Hundt wrote:
>>
>> I am dealing with a box type that is specified in multiple coordinate
>> systems because it is translating from vector to raster. One point
>> type is integer based for the location in an image (cartesian), and
>> the other is a point defined with doubles, also a cartesian system.
>
>
> Interesting.
>
>
>> I initially tried to define the coordinates by defining tags
>> inheriting from the point_type tag assuming that tag_cast would be
>> applied, keeping all existing geometry calls functional as follows:
>>
>> struct grid_point_tag : boost::geometry::point_tag {};
>> struct world_point_tag : boost::geometry::point_tag {};
>>
>> However, this turned out not to be the case as nearly all uses of
>> point_tag don't use tag_cast. Alternatively I can define an entirely
>> new tag system for these points and use that. While it would work
>> around the problem I don't feel like it is the best way to solve it.
>> If there are any ideas they would be greatly appreciated.
>
>
> Yes, the tag_cast was designed for other purposes (though I agree it could be used wider), so for point_tag it is not used. It might probably be done if it enables new possibilities.
>
> Actually I don't see yet how it would solve your problem. The point_type defined by your box should be sometimes one point_type, sometimes another point_type? That is not solved out of the box. So basically you already have (for the library) two box types available, if I see it right.
>
> One of the options (I did that recently for one of my projects) is creating two different wrapper classes with different traits registrations. You then have effectively two types.
>
> So you could create a class BoxInGrid (and implement all the traits)
> and a class BoxInWorld (also implements all the traits but defining another point type)
>
> These classes could take a (either const or not const) reference to your box such that it stays as light-weight as possible (but admitted, still a wrapper).
>
> Alternatively (probably better) you could of course use only one wrapper, and implement traits for the original too. Then also you have two different box types.
>
> Hope this helps.
>
> Regards, Barend
>
> _______________________________________________
> Geometry mailing list
> Geometry_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/geometry


Geometry list run by mateusz at loskot.net