![]() |
Home | Libraries | People | FAQ | More |
This example demonstrates the implementation of two non-SI units of length, the nautical mile :
namespace nautical { struct length_base_unit : boost::units::base_unit<length_base_unit, length_dimension, 1> { static std::string name() { return "nautical mile"; } static std::string symbol() { return "nmi"; } }; typedef boost::units::make_system<length_base_unit>::type system; /// unit typedefs typedef unit<length_dimension,system> length; static const length mile,miles; } // namespace nautical // helper for conversions between nautical length and si length BOOST_UNITS_DEFINE_CONVERSION_FACTOR(nautical::length_base_unit, boost::units::si::meter_base_unit, double, 1.852e3);
and the imperial foot :
namespace imperial { struct length_base_unit : boost::units::base_unit<length_base_unit, length_dimension, 2> { static std::string name() { return "foot"; } static std::string symbol() { return "ft"; } }; typedef boost::units::make_system<length_base_unit>::type system; /// unit typedefs typedef unit<length_dimension,system> length; static const length foot,feet; } // imperial // helper for conversions between imperial length and si length BOOST_UNITS_DEFINE_CONVERSION_FACTOR(imperial::length_base_unit, boost::units::si::meter_base_unit, double, 1.0/3.28083989501312);
These units include conversions between themselves and the meter. Three functions for computing radar beam height from radar range and the local earth radius are defined. The first takes arguments in one system and returns a value in the same system :
template<class System,typename T> quantity<unit<boost::units::length_dimension,System>,T> radar_beam_height(const quantity<unit<length_dimension,System>,T>& radar_range, const quantity<unit<length_dimension,System>,T>& earth_radius, T k = 4.0/3.0) { return quantity<unit<length_dimension,System>,T> (pow<2>(radar_range)/(2.0*k*earth_radius)); }
The second is similar, but is templated on return type, so that the arguments are converted to the return unit system internally :
template<class return_type,class System1,class System2,typename T> return_type radar_beam_height(const quantity<unit<length_dimension,System1>,T>& radar_range, const quantity<unit<length_dimension,System2>,T>& earth_radius, T k = 4.0/3.0) { // need to decide which system to use for calculation const return_type rr(radar_range), er(earth_radius); return return_type(pow<2>(rr)/(2.0*k*er)); }
Finally, the third function is an empirical approximation that is only valid for radar ranges specified in nautical miles, returning beam height in feet. This function uses the heterogeneous unit of nautical miles per square root of feet to ensure dimensional correctness :
quantity<imperial::length> radar_beam_height(const quantity<nautical::length>& range) { return quantity<imperial::length> (pow<2>(range/(1.23*nautical::miles/root<2>(imperial::feet)))); }
With these, we can compute radar beam height in various unit systems :
const quantity<nautical::length> radar_range(300.0*miles); const quantity<si::length> earth_radius(6371.0087714*kilo*meters); const quantity<si::length> beam_height_1(radar_beam_height(quantity<si::length>(radar_range),earth_radius)); const quantity<nautical::length> beam_height_2(radar_beam_height(radar_range,quantity<nautical::length>(earth_radius))); const quantity<si::length> beam_height_3(radar_beam_height< quantity<si::length> >(radar_range,earth_radius)); const quantity<nautical::length> beam_height_4(radar_beam_height< quantity<nautical::length> >(radar_range,earth_radius));
giving
radar range : 300 nmi earth radius : 6.37101e+06 m beam height 1 : 18169.7 m beam height 2 : 9.81085 nmi beam height 3 : 18169.7 m beam height 4 : 9.81085 nmi beam height approx : 59488.4 ft beam height approx : 18132.1 m