File indexing completed on 2024-11-15 09:10:16
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_LINE_LINE_INTERSECTION_HPP
0010 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_LINE_LINE_INTERSECTION_HPP
0011
0012 #include <boost/geometry/algorithms/detail/make/make.hpp>
0013 #include <boost/geometry/arithmetic/infinite_line_functions.hpp>
0014 #include <boost/geometry/util/math.hpp>
0015
0016 namespace boost { namespace geometry
0017 {
0018
0019
0020 #ifndef DOXYGEN_NO_DETAIL
0021 namespace detail { namespace buffer
0022 {
0023
0024 struct line_line_intersection
0025 {
0026 template <typename Point>
0027 static Point between_point(Point const& a, Point const& b)
0028 {
0029 Point result;
0030 geometry::set<0>(result, (geometry::get<0>(a) + geometry::get<0>(b)) / 2.0);
0031 geometry::set<1>(result, (geometry::get<1>(a) + geometry::get<1>(b)) / 2.0);
0032 return result;
0033 }
0034
0035 template <typename Point>
0036 static bool
0037 apply(Point const& pi, Point const& pj, Point const& qi, Point const& qj,
0038 Point const& vertex, bool equidistant, Point& ip)
0039 {
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 using ct = typename coordinate_type<Point>::type;
0068
0069 auto const p = detail::make::make_infinite_line<ct>(pi, pj);
0070 auto const q = detail::make::make_infinite_line<ct>(qi, qj);
0071
0072 using line = decltype(p);
0073 using arithmetic::determinant;
0074 using arithmetic::assign_intersection_point;
0075
0076
0077
0078
0079 auto const denominator_pq = determinant<line, &line::a, &line::b>(p, q);
0080 static decltype(denominator_pq) const zero = 0;
0081
0082 if (equidistant)
0083 {
0084 auto const between = between_point(pj, qi);
0085 auto const r = detail::make::make_infinite_line<ct>(vertex, between);
0086 auto const denominator_pr = determinant<line, &line::a, &line::b>(p, r);
0087
0088 if (math::equals(denominator_pq, zero)
0089 && math::equals(denominator_pr, zero))
0090 {
0091
0092 return false;
0093 }
0094
0095 ip = geometry::math::abs(denominator_pq) > geometry::math::abs(denominator_pr)
0096 ? assign_intersection_point<Point>(p, q, denominator_pq)
0097 : assign_intersection_point<Point>(p, r, denominator_pr);
0098 }
0099 else
0100 {
0101 if (math::equals(denominator_pq, zero))
0102 {
0103 return false;
0104 }
0105 ip = assign_intersection_point<Point>(p, q, denominator_pq);
0106 }
0107
0108 return true;
0109 }
0110 };
0111
0112
0113 }}
0114 #endif
0115
0116
0117 }}
0118
0119
0120 #endif