File indexing completed on 2025-01-18 09:36:42
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_MITER_HPP
0010 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_BUFFER_JOIN_MITER_HPP
0011
0012 #include <boost/geometry/core/assert.hpp>
0013 #include <boost/geometry/core/cs.hpp>
0014 #include <boost/geometry/policies/compare.hpp>
0015 #include <boost/geometry/util/math.hpp>
0016 #include <boost/geometry/util/select_most_precise.hpp>
0017
0018 #include <boost/geometry/strategies/buffer.hpp>
0019
0020
0021 namespace boost { namespace geometry
0022 {
0023
0024 namespace strategy { namespace buffer
0025 {
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 class join_miter
0053 {
0054 public:
0055
0056
0057
0058 explicit inline join_miter(double miter_limit = 5.0)
0059 : m_miter_limit(valid_limit(miter_limit))
0060 {}
0061
0062 #ifndef DOXYGEN_SHOULD_SKIP_THIS
0063
0064 template <typename Point, typename DistanceType, typename RangeOut>
0065 inline bool apply(Point const& ip, Point const& vertex,
0066 Point const& perp1, Point const& perp2,
0067 DistanceType const& buffer_distance,
0068 RangeOut& range_out) const
0069 {
0070 geometry::equal_to<Point> equals;
0071 if (equals(ip, vertex))
0072 {
0073 return false;
0074 }
0075 if (equals(perp1, perp2))
0076 {
0077 return false;
0078 }
0079
0080 typedef typename coordinate_type<Point>::type coordinate_type;
0081 typedef typename geometry::select_most_precise
0082 <
0083 coordinate_type,
0084 double
0085 >::type promoted_type;
0086
0087 Point p = ip;
0088
0089
0090
0091
0092 promoted_type const dx = get<0>(p) - get<0>(vertex);
0093 promoted_type const dy = get<1>(p) - get<1>(vertex);
0094
0095 promoted_type const distance = geometry::math::sqrt(dx * dx + dy * dy);
0096
0097 promoted_type const max_distance
0098 = m_miter_limit * geometry::math::abs(buffer_distance);
0099
0100 if (distance > max_distance)
0101 {
0102 BOOST_GEOMETRY_ASSERT(distance != 0.0);
0103
0104 promoted_type const proportion = max_distance / distance;
0105 set<0>(p, get<0>(vertex) + dx * proportion);
0106 set<1>(p, get<1>(vertex) + dy * proportion);
0107 }
0108
0109 range_out.push_back(perp1);
0110 range_out.push_back(p);
0111 range_out.push_back(perp2);
0112 return true;
0113 }
0114
0115 template <typename NumericType>
0116 inline NumericType max_distance(NumericType const& distance) const
0117 {
0118 return distance * m_miter_limit;
0119 }
0120
0121 #endif
0122
0123 private :
0124 double valid_limit(double miter_limit) const
0125 {
0126 if (miter_limit < 1.0)
0127 {
0128
0129 miter_limit = 1.0;
0130 }
0131 return miter_limit;
0132 }
0133
0134 double m_miter_limit;
0135 };
0136
0137 }}
0138
0139
0140 }}
0141
0142 #endif