Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:36:51

0001 // Boost.Geometry
0002 
0003 // Copyright (c) 2021, Oracle and/or its affiliates.
0004 
0005 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0006 
0007 // Licensed under the Boost Software License version 1.0.
0008 // http://www.boost.org/users/license.html
0009 
0010 #ifndef BOOST_GEOMETRY_STRATEGY_SPHERICAL_AREA_BOX_HPP
0011 #define BOOST_GEOMETRY_STRATEGY_SPHERICAL_AREA_BOX_HPP
0012 
0013 
0014 #include <boost/geometry/core/coordinate_type.hpp>
0015 #include <boost/geometry/core/coordinate_dimension.hpp>
0016 #include <boost/geometry/core/radian_access.hpp>
0017 #include <boost/geometry/srs/sphere.hpp>
0018 #include <boost/geometry/strategies/spherical/get_radius.hpp>
0019 #include <boost/geometry/strategy/area.hpp>
0020 #include <boost/geometry/util/normalize_spheroidal_box_coordinates.hpp>
0021 
0022 
0023 namespace boost { namespace geometry
0024 {
0025 
0026 namespace strategy { namespace area
0027 {
0028 
0029 // https://math.stackexchange.com/questions/131735/surface-element-in-spherical-coordinates
0030 // http://www.cs.cmu.edu/afs/cs/academic/class/16823-s16/www/pdfs/appearance-modeling-3.pdf
0031 // https://www.astronomyclub.xyz/celestial-sphere-2/solid-angle-on-the-celestial-sphere.html
0032 // https://mathworld.wolfram.com/SolidAngle.html
0033 // https://en.wikipedia.org/wiki/Spherical_coordinate_system
0034 // Note that the equations used in the above articles are spherical polar coordinates.
0035 // We use spherical equatorial, so the equation is different:
0036 // assume(y_max > y_min);
0037 // assume(x_max > x_min);
0038 // /* because of polar to equatorial conversion */
0039 // sin(%pi / 2 - y);
0040 // O: r ^ 2 * cos(y);
0041 // S: integrate(integrate(O, y, y_min, y_max), x, x_min, x_max);
0042 template
0043 <
0044     typename RadiusTypeOrSphere = double,
0045     typename CalculationType = void
0046 >
0047 class spherical_box
0048 {
0049     typedef typename strategy_detail::get_radius
0050         <
0051             RadiusTypeOrSphere
0052         >::type radius_type;
0053 
0054 public:
0055     template <typename Box>
0056     struct result_type
0057         : strategy::area::detail::result_type
0058             <
0059                 Box,
0060                 CalculationType
0061             >
0062     {};
0063 
0064     // For consistency with other strategies the radius is set to 1
0065     inline spherical_box()
0066         : m_radius(1.0)
0067     {}
0068 
0069     template <typename RadiusOrSphere>
0070     explicit inline spherical_box(RadiusOrSphere const& radius_or_sphere)
0071         : m_radius(strategy_detail::get_radius
0072                     <
0073                         RadiusOrSphere
0074                     >::apply(radius_or_sphere))
0075     {}
0076 
0077     template <typename Box>
0078     inline auto apply(Box const& box) const
0079     {
0080         typedef typename result_type<Box>::type return_type;
0081 
0082         return_type x_min = get_as_radian<min_corner, 0>(box); // lon
0083         return_type y_min = get_as_radian<min_corner, 1>(box); // lat
0084         return_type x_max = get_as_radian<max_corner, 0>(box);
0085         return_type y_max = get_as_radian<max_corner, 1>(box);
0086 
0087         if (x_min == x_max || y_max == y_min)
0088         {
0089             return return_type(0);
0090         }
0091 
0092         math::normalize_spheroidal_box_coordinates<radian>(x_min, y_min, x_max, y_max);
0093 
0094         return (x_max - x_min)
0095              * (sin(y_max) - sin(y_min))
0096              * return_type(m_radius * m_radius);
0097     }
0098 
0099     srs::sphere<radius_type> model() const
0100     {
0101         return srs::sphere<radius_type>(m_radius);
0102     }
0103 
0104 private:
0105     radius_type m_radius;
0106 };
0107 
0108 
0109 }} // namespace strategy::area
0110 
0111 
0112 }} // namespace boost::geometry
0113 
0114 
0115 #endif // BOOST_GEOMETRY_STRATEGY_SPHERICAL_AREA_BOX_HPP