File indexing completed on 2025-09-16 08:35:31
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 using promoted_type = typename geometry::select_most_precise
0081 <
0082 coordinate_type_t<Point>,
0083 double
0084 >::type;
0085
0086 Point p = ip;
0087
0088
0089
0090
0091 promoted_type const dx = get<0>(p) - get<0>(vertex);
0092 promoted_type const dy = get<1>(p) - get<1>(vertex);
0093
0094 promoted_type const distance = geometry::math::sqrt(dx * dx + dy * dy);
0095
0096 promoted_type const max_distance
0097 = m_miter_limit * geometry::math::abs(buffer_distance);
0098
0099 if (distance > max_distance)
0100 {
0101 BOOST_GEOMETRY_ASSERT(distance != 0.0);
0102
0103 promoted_type const proportion = max_distance / distance;
0104 set<0>(p, get<0>(vertex) + dx * proportion);
0105 set<1>(p, get<1>(vertex) + dy * proportion);
0106 }
0107
0108 range_out.push_back(perp1);
0109 range_out.push_back(p);
0110 range_out.push_back(perp2);
0111 return true;
0112 }
0113
0114 template <typename NumericType>
0115 inline NumericType max_distance(NumericType const& distance) const
0116 {
0117 return distance * m_miter_limit;
0118 }
0119
0120 #endif
0121
0122 private :
0123 double valid_limit(double miter_limit) const
0124 {
0125 if (miter_limit < 1.0)
0126 {
0127
0128 miter_limit = 1.0;
0129 }
0130 return miter_limit;
0131 }
0132
0133 double m_miter_limit;
0134 };
0135
0136 }}
0137
0138
0139 }}
0140
0141 #endif