Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // Boost.Geometry (aka GGL, Generic Geometry Library)
0002 // Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
0003 // Use, modification and distribution is subject to the Boost Software License,
0004 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
0005 // http://www.boost.org/LICENSE_1_0.txt)
0006 
0007 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_SIDE_STRAIGHT_HPP
0008 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_SIDE_STRAIGHT_HPP
0009 
0010 #include <cstddef>
0011 
0012 #include <boost/math/special_functions/fpclassify.hpp>
0013 
0014 #include <boost/geometry/core/coordinate_type.hpp>
0015 #include <boost/geometry/core/access.hpp>
0016 #include <boost/geometry/util/math.hpp>
0017 #include <boost/geometry/util/select_most_precise.hpp>
0018 
0019 #include <boost/geometry/strategies/buffer.hpp>
0020 #include <boost/geometry/strategies/side.hpp>
0021 
0022 
0023 
0024 namespace boost { namespace geometry
0025 {
0026 
0027 namespace strategy { namespace buffer
0028 {
0029 
0030 
0031 
0032 /*!
0033 \brief Let the buffer use straight sides along segments (the default)
0034 \ingroup strategies
0035 \details This strategy can be used as SideStrategy for the buffer algorithm.
0036     It is currently the only provided strategy for this purpose
0037 
0038 \qbk{
0039 [heading Example]
0040 See the examples for other buffer strategies\, for example
0041 [link geometry.reference.strategies.strategy_buffer_join_round join_round]
0042 [heading See also]
0043 \* [link geometry.reference.algorithms.buffer.buffer_7_with_strategies buffer (with strategies)]
0044 }
0045  */
0046 class side_straight
0047 {
0048 public :
0049 #ifndef DOXYGEN_SHOULD_SKIP_THIS
0050 
0051     // Returns true if the buffer distance is always the same
0052     static inline bool equidistant()
0053     {
0054         return true;
0055     }
0056 
0057     template
0058     <
0059         typename Point,
0060         typename OutputRange,
0061         typename DistanceStrategy
0062     >
0063     static inline result_code apply(
0064                 Point const& input_p1, Point const& input_p2,
0065                 buffer_side_selector side,
0066                 DistanceStrategy const& distance,
0067                 OutputRange& output_range)
0068     {
0069         typedef typename coordinate_type<Point>::type coordinate_type;
0070         typedef typename geometry::select_most_precise
0071         <
0072             coordinate_type,
0073             double
0074         >::type promoted_type;
0075 
0076         // Generate a block along (left or right of) the segment
0077 
0078         // Simulate a vector d (dx,dy)
0079         promoted_type const dx = get<0>(input_p2) - get<0>(input_p1);
0080         promoted_type const dy = get<1>(input_p2) - get<1>(input_p1);
0081 
0082         // For normalization [0,1] (=dot product d.d, sqrt)
0083         promoted_type const length = geometry::math::sqrt(dx * dx + dy * dy);
0084 
0085         if (! boost::math::isfinite(length))
0086         {
0087             // In case of coordinates differences of e.g. 1e300, length
0088             // will overflow and we should not generate output
0089 #ifdef BOOST_GEOMETRY_DEBUG_BUFFER_WARN
0090             std::cout << "Error in length calculation for points "
0091                 << geometry::wkt(input_p1) << " " << geometry::wkt(input_p2)
0092                 << " length: " << length << std::endl;
0093 #endif
0094             return result_error_numerical;
0095         }
0096 
0097         if (geometry::math::equals(length, 0))
0098         {
0099             // Coordinates are simplified and therefore most often not equal.
0100             // But if simplify is skipped, or for lines with two
0101             // equal points, length is 0 and we cannot generate output.
0102             return result_no_output;
0103         }
0104 
0105         promoted_type const d = distance.apply(input_p1, input_p2, side);
0106 
0107         // Generate the normalized perpendicular p, to the left (ccw)
0108         promoted_type const px = -dy / length;
0109         promoted_type const py = dx / length;
0110 
0111         if (geometry::math::equals(px, 0)
0112             && geometry::math::equals(py, 0))
0113         {
0114             // This basically should not occur - because of the checks above.
0115             // There are no unit tests triggering this condition
0116 #ifdef BOOST_GEOMETRY_DEBUG_BUFFER_WARN
0117             std::cout << "Error in perpendicular calculation for points "
0118                 << geometry::wkt(input_p1) << " " << geometry::wkt(input_p2)
0119                 << " length: " << length
0120                 << " distance: " << d
0121                 << std::endl;
0122 #endif
0123             return result_no_output;
0124         }
0125 
0126         output_range.resize(2);
0127 
0128         set<0>(output_range.front(), get<0>(input_p1) + px * d);
0129         set<1>(output_range.front(), get<1>(input_p1) + py * d);
0130         set<0>(output_range.back(), get<0>(input_p2) + px * d);
0131         set<1>(output_range.back(), get<1>(input_p2) + py * d);
0132 
0133         return result_normal;
0134     }
0135 #endif // DOXYGEN_SHOULD_SKIP_THIS
0136 };
0137 
0138 
0139 }} // namespace strategy::buffer
0140 
0141 }} // namespace boost::geometry
0142 
0143 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_SIDE_STRAIGHT_HPP