From 7adc8b2d06e99714b36e6801a1f56f441c5834de Mon Sep 17 00:00:00 2001 From: Barend Gehrels Date: Sun, 2 Jan 2011 14:11:22 +0000 Subject: [PATCH] Added example to work with units [SVN r67570] --- example/08_units_example.cpp | 207 ++++++++++++++++++++++++++++++++ example/08_units_example.vcproj | 171 ++++++++++++++++++++++++++ example/Jamfile.v2 | 1 + 3 files changed, 379 insertions(+) create mode 100644 example/08_units_example.cpp create mode 100644 example/08_units_example.vcproj diff --git a/example/08_units_example.cpp b/example/08_units_example.cpp new file mode 100644 index 000000000..43f099823 --- /dev/null +++ b/example/08_units_example.cpp @@ -0,0 +1,207 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// +// Copyright Barend Gehrels 2011, Geodan, Amsterdam, the Netherlands +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Example combining Boost.Geometry with Boost.Units + +#include + +#include + + +#include +#include +#include +#include + + +// TEMPORARY this will go to somewhere within Boost.Geometry +namespace boost { namespace geometry +{ + +namespace cs +{ + +template +struct units_cartesian {}; + +} + +namespace traits +{ +template +struct cs_tag > +{ + typedef cartesian_tag type; +}; + +} + + +namespace model +{ + +// Define a point type to interoperate with Boost.Units, having +// 1. a constructor taking quantities +// 2. defining a quantified coordinate system +// Note that all values are still stored in "normal" types as double +template > +class quantity_point : public model::point +{ + typedef boost::units::quantity qtype; + +public : + + // Templated constructor to allow constructing with other units then qtype, + // e.g. to convert from centimeters to meters + template + inline quantity_point(Q const& x, Q const& y) + : model::point( + qtype(x).value(), + qtype(y).value()) + {} +}; + +} + + +// Adapt quantity_point to the Point Concept +#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS +namespace traits +{ + +template +struct tag > +{ + typedef point_tag type; +}; + +template +struct coordinate_type > +{ + typedef CoordinateType type; +}; + +template +struct coordinate_system > +{ + typedef CoordinateSystem type; +}; + +template +struct dimension > + : boost::mpl::int_ +{}; + +template +struct access, Dimension > +{ + static inline CoordinateType get( + model::quantity_point const& p) + { + return p.template get(); + } + + static inline void set(model::quantity_point& p, + CoordinateType const& value) + { + p.template set(value); + } +}; + +} // namespace traits +#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS + + + +// For extra support for functions as distance,area,get,set +namespace units +{ + namespace detail + { + // Define an extra meta-function to get the units of a coordinate system + template + struct unit_dimension + { + // define it as dimensionless + // or MPL ASSERT + }; + + template + struct unit_dimension > + { + typedef U type; + }; + } + + // Define an extra metafunction to define the quantity of a Geometry type + template ::type> + struct quantity + { + typedef boost::units::quantity + < + typename detail::unit_dimension + < + typename coordinate_system::type + >::type, + CT + > type; + }; + + + template + inline typename quantity::type>::type + distance(Geometry1 const& g1, Geometry2 const& g2) + { + typedef typename quantity::type>::type q; + return q::from_value(geometry::distance(g1, g2)); + } + + template + inline typename quantity::type get(Point const& p) + { + typedef typename quantity::type q; + return q::from_value(geometry::get(p)); + } +} + +}} +// END TEMPORARY + + + +int main(void) +{ + using namespace boost::geometry; + using namespace boost::units; + + // 1: using it directly + { + typedef model::quantity_point point; + point p1(1 * si::meter, 2 * si::meter); + point p2(3 * si::meter, 4 * si::meter); + + std::cout << get<0>(p2) << std::endl; + + // This is a little inconvenient: + quantity d = distance(p1, p2) * si::meter; + + std::cout << d << std::endl; + } + + // 2: same but now using centimeters, and using boost::geometry::units:: + { + typedef model::quantity_point point; + point p1(1 * si::meter, 2 * si::meter); + point p2(3 * si::meter, 4 * si::meter); + + std::cout << boost::geometry::units::get<0>(p2) << std::endl; + quantity d = boost::geometry::units::distance(p1, p2); + std::cout << d << std::endl; + } + + return 0; +} diff --git a/example/08_units_example.vcproj b/example/08_units_example.vcproj new file mode 100644 index 000000000..502f492ad --- /dev/null +++ b/example/08_units_example.vcproj @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 index 27db0d251..03ba234c1 100644 --- a/example/Jamfile.v2 +++ b/example/Jamfile.v2 @@ -20,6 +20,7 @@ exe 06_a_transformation_example : 06_a_transformation_example.cpp ; exe 06_b_transformation_example : 06_b_transformation_example.cpp ; exe 07_a_graph_route_example : 07_a_graph_route_example.cpp ; exe 07_b_graph_route_example : 07_b_graph_route_example.cpp ; +exe 08_units_example : 08_units_example.cpp ; exe c01_custom_point_example : c01_custom_point_example.cpp ; exe c02_custom_box_example : c02_custom_box_example.cpp ;