Brian Silverman | a8ce4c3 | 2018-08-04 23:57:09 -0700 | [diff] [blame^] | 1 | // Boost.Units - A C++ library for zero-overhead dimensional analysis and |
| 2 | // unit/quantity manipulation and conversion |
| 3 | // |
| 4 | // Copyright (C) 2003-2008 Matthias Christian Schabel |
| 5 | // Copyright (C) 2008 Steven Watanabe |
| 6 | // |
| 7 | // Distributed under the Boost Software License, Version 1.0. (See |
| 8 | // accompanying file LICENSE_1_0.txt or copy at |
| 9 | // http://www.boost.org/LICENSE_1_0.txt) |
| 10 | |
| 11 | /** |
| 12 | \file |
| 13 | |
| 14 | \brief radar_beam_height.cpp |
| 15 | |
| 16 | \details |
| 17 | Demonstrate library usage for user test cases suggested by Michael Fawcett. |
| 18 | |
| 19 | Output: |
| 20 | @verbatim |
| 21 | |
| 22 | //[radar_beam_height_output |
| 23 | radar range : 300 nmi |
| 24 | earth radius : 6.37101e+06 m |
| 25 | beam height 1 : 18169.7 m |
| 26 | beam height 2 : 9.81085 nmi |
| 27 | beam height 3 : 18169.7 m |
| 28 | beam height 4 : 9.81085 nmi |
| 29 | beam height approx : 59488.4 ft |
| 30 | beam height approx : 18132.1 m |
| 31 | //] |
| 32 | |
| 33 | @endverbatim |
| 34 | **/ |
| 35 | |
| 36 | #include <iostream> |
| 37 | |
| 38 | #include <boost/units/conversion.hpp> |
| 39 | #include <boost/units/io.hpp> |
| 40 | #include <boost/units/pow.hpp> |
| 41 | #include <boost/units/systems/si.hpp> |
| 42 | #include <boost/units/systems/si/prefixes.hpp> |
| 43 | |
| 44 | using boost::units::length_dimension; |
| 45 | using boost::units::pow; |
| 46 | using boost::units::root; |
| 47 | using boost::units::quantity; |
| 48 | using boost::units::unit; |
| 49 | |
| 50 | //[radar_beam_height_class_snippet_1 |
| 51 | namespace nautical { |
| 52 | |
| 53 | struct length_base_unit : |
| 54 | boost::units::base_unit<length_base_unit, length_dimension, 1> |
| 55 | { |
| 56 | static std::string name() { return "nautical mile"; } |
| 57 | static std::string symbol() { return "nmi"; } |
| 58 | }; |
| 59 | |
| 60 | typedef boost::units::make_system<length_base_unit>::type system; |
| 61 | |
| 62 | /// unit typedefs |
| 63 | typedef unit<length_dimension,system> length; |
| 64 | |
| 65 | static const length mile,miles; |
| 66 | |
| 67 | } // namespace nautical |
| 68 | |
| 69 | // helper for conversions between nautical length and si length |
| 70 | BOOST_UNITS_DEFINE_CONVERSION_FACTOR(nautical::length_base_unit, |
| 71 | boost::units::si::meter_base_unit, |
| 72 | double, 1.852e3); |
| 73 | //] |
| 74 | |
| 75 | //[radar_beam_height_class_snippet_2 |
| 76 | namespace imperial { |
| 77 | |
| 78 | struct length_base_unit : |
| 79 | boost::units::base_unit<length_base_unit, length_dimension, 2> |
| 80 | { |
| 81 | static std::string name() { return "foot"; } |
| 82 | static std::string symbol() { return "ft"; } |
| 83 | }; |
| 84 | |
| 85 | typedef boost::units::make_system<length_base_unit>::type system; |
| 86 | |
| 87 | /// unit typedefs |
| 88 | typedef unit<length_dimension,system> length; |
| 89 | |
| 90 | static const length foot,feet; |
| 91 | |
| 92 | } // imperial |
| 93 | |
| 94 | // helper for conversions between imperial length and si length |
| 95 | BOOST_UNITS_DEFINE_CONVERSION_FACTOR(imperial::length_base_unit, |
| 96 | boost::units::si::meter_base_unit, |
| 97 | double, 1.0/3.28083989501312); |
| 98 | //] |
| 99 | |
| 100 | // radar beam height functions |
| 101 | //[radar_beam_height_function_snippet_1 |
| 102 | template<class System,typename T> |
| 103 | constexpr |
| 104 | quantity<unit<boost::units::length_dimension,System>,T> |
| 105 | radar_beam_height(const quantity<unit<length_dimension,System>,T>& radar_range, |
| 106 | const quantity<unit<length_dimension,System>,T>& earth_radius, |
| 107 | T k = 4.0/3.0) |
| 108 | { |
| 109 | return quantity<unit<length_dimension,System>,T> |
| 110 | (pow<2>(radar_range)/(2.0*k*earth_radius)); |
| 111 | } |
| 112 | //] |
| 113 | |
| 114 | //[radar_beam_height_function_snippet_2 |
| 115 | template<class return_type,class System1,class System2,typename T> |
| 116 | constexpr |
| 117 | return_type |
| 118 | radar_beam_height(const quantity<unit<length_dimension,System1>,T>& radar_range, |
| 119 | const quantity<unit<length_dimension,System2>,T>& earth_radius, |
| 120 | T k = 4.0/3.0) |
| 121 | { |
| 122 | // need to decide which system to use for calculation |
| 123 | return pow<2>(static_cast<return_type>(radar_range)) |
| 124 | / (2.0*k*static_cast<return_type>(earth_radius)); |
| 125 | } |
| 126 | //] |
| 127 | |
| 128 | //[radar_beam_height_function_snippet_3 |
| 129 | constexpr |
| 130 | quantity<imperial::length> |
| 131 | radar_beam_height(const quantity<nautical::length>& range) |
| 132 | { |
| 133 | return quantity<imperial::length> |
| 134 | (pow<2>(range/(1.23*nautical::miles/root<2>(imperial::feet)))); |
| 135 | } |
| 136 | //] |
| 137 | |
| 138 | int main(void) |
| 139 | { |
| 140 | using namespace boost::units; |
| 141 | using namespace boost::units::si; |
| 142 | using namespace nautical; |
| 143 | |
| 144 | //[radar_beam_height_snippet_1 |
| 145 | const quantity<nautical::length> radar_range(300.0*miles); |
| 146 | const quantity<si::length> earth_radius(6371.0087714*kilo*meters); |
| 147 | |
| 148 | const quantity<si::length> beam_height_1(radar_beam_height(quantity<si::length>(radar_range),earth_radius)); |
| 149 | const quantity<nautical::length> beam_height_2(radar_beam_height(radar_range,quantity<nautical::length>(earth_radius))); |
| 150 | const quantity<si::length> beam_height_3(radar_beam_height< quantity<si::length> >(radar_range,earth_radius)); |
| 151 | const quantity<nautical::length> beam_height_4(radar_beam_height< quantity<nautical::length> >(radar_range,earth_radius)); |
| 152 | //] |
| 153 | |
| 154 | std::cout << "radar range : " << radar_range << std::endl |
| 155 | << "earth radius : " << earth_radius << std::endl |
| 156 | << "beam height 1 : " << beam_height_1 << std::endl |
| 157 | << "beam height 2 : " << beam_height_2 << std::endl |
| 158 | << "beam height 3 : " << beam_height_3 << std::endl |
| 159 | << "beam height 4 : " << beam_height_4 << std::endl |
| 160 | << "beam height approx : " << radar_beam_height(radar_range) |
| 161 | << std::endl |
| 162 | << "beam height approx : " |
| 163 | << quantity<si::length>(radar_beam_height(radar_range)) |
| 164 | << std::endl << std::endl; |
| 165 | |
| 166 | return 0; |
| 167 | } |