Boost logo

Boost Users :

Subject: Re: [Boost-users] [units][geometry] subtract_typeof_helper<> help!
From: Barend Gehrels (barend_at_[hidden])
Date: 2011-01-02 09:18:25


Hi Alfredo,

> Great, please keep me (us) posted

Actually the timing is convenient because this indeed was still an
action to be taken, mentioned in the review report.

> What I have so far is for example
> using namespace boost::geometry;
> using namespace boost::units;
> model::point<double, 3, cs::units_cartesian<si::length> >
> p1(1.*si::meter,2.*si::meter,3.*si::meter);
> std::clog << distance(p1,p1) << std::endl; // outputs 0. * meter

This does not work for me. The type declaration works, but coordinates
are still doubles here. The construction effectively translates to
"double d = 1.*si::meter". This gives me the message "cannot convert
from 'boost::units::quantity<Unit>' to 'double'". So how does this work
for you?

>
> #include<boost/geometry/geometries/adapted/boost_array_units_cartesian.hpp>
> ...
> using namespace boost::units;
> boost::array<quantity<si::length>, 3>
> p5={{10.*si::meter,11.*si::meter,12.*si::meter}};
> std::clog << distance(p5,p5) << std::endl; //outputs 0. * meter
>

Construction works here for me, but calculating distance does not.
Because distance behind the screens takes the square root, after
squaring. This requires thorough integration with Boost.Units at those
places, which is not planned.

> the implementation I have is very primitive and it is practically a
> mockup because it bypasses most of the features of the Boost.Geometry
> library; mainly because I didn't understand them internally.

So Boost.Geometry is not dependant on Boost.Units. I think the way to go
is define a point type using a coordinate system using Boost.Units, like
you did, and also add quantities there.

I just tried that. However, the output is then still in values, so
distance will result a value (e.g. double). It runs like this:

// Note that the last 3 template parameters have defaults
typedef model::quantity_point<si::length, 2, double,
cs::units_cartesian<si::length> > point;
point p1(1 * meter, 2 * meter); // only quantities expected
point p2(3 * meter, 4 * meter);
quantity<si::length> d = distance(p1, p2) * si::meter;

Then it IS possible to create a set of overloaded functions, e.g.
boost::geometry::units::set(point, quantity) to set it from a quantity
boost::geometry::units::get(point) to return a quantity
boost::geometry::units::distance(a,b) -> returns a quantity in the
coordinate dimensions from the measured distance
boost::geometry::units::area(a) -> returns a quantity e.g. in
square_meters from a polygon

So I added two of these functions as well, giving:

std::cout << units::get<0>(p2) << std::endl;
quantity<si::length> d = units::distance(p1, p2);
std::cout << d << std::endl;

reporting all quantities including units. It required some small
additional metafunctions as well.

I just committed it, for the moment as a new example (including
definitions), here:
http://bit.ly/dEip8s

Regards, Barend


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net