File indexing completed on 2025-01-18 09:36:42
0001
0002
0003
0004
0005
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
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 class side_straight
0047 {
0048 public :
0049 #ifndef DOXYGEN_SHOULD_SKIP_THIS
0050
0051
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
0077
0078
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
0083 promoted_type const length = geometry::math::sqrt(dx * dx + dy * dy);
0084
0085 if (! boost::math::isfinite(length))
0086 {
0087
0088
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
0100
0101
0102 return result_no_output;
0103 }
0104
0105 promoted_type const d = distance.apply(input_p1, input_p2, side);
0106
0107
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
0115
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
0136 };
0137
0138
0139 }}
0140
0141 }}
0142
0143 #endif