Chris@16
|
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
|
Chris@16
|
2
|
Chris@16
|
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
Chris@16
|
4
|
Chris@16
|
5 // Use, modification and distribution is subject to the Boost Software License,
|
Chris@16
|
6 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8
|
Chris@16
|
9 #ifndef BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_DE9IM_HPP
|
Chris@16
|
10 #define BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_DE9IM_HPP
|
Chris@16
|
11
|
Chris@16
|
12
|
Chris@16
|
13 #include <boost/geometry/strategies/intersection_result.hpp>
|
Chris@16
|
14 #include <boost/geometry/util/math.hpp>
|
Chris@16
|
15 #include <boost/geometry/util/select_coordinate_type.hpp>
|
Chris@16
|
16
|
Chris@16
|
17
|
Chris@16
|
18 namespace boost { namespace geometry
|
Chris@16
|
19 {
|
Chris@16
|
20
|
Chris@16
|
21 namespace policies { namespace relate
|
Chris@16
|
22 {
|
Chris@16
|
23
|
Chris@16
|
24
|
Chris@16
|
25 template <typename S1, typename S2>
|
Chris@16
|
26 struct segments_de9im
|
Chris@16
|
27 {
|
Chris@16
|
28 typedef de9im_segment return_type;
|
Chris@16
|
29 typedef S1 segment_type1;
|
Chris@16
|
30 typedef S2 segment_type2;
|
Chris@16
|
31 typedef typename select_coordinate_type<S1, S2>::type coordinate_type;
|
Chris@16
|
32
|
Chris@16
|
33 static inline return_type rays_intersect(bool on_segment,
|
Chris@16
|
34 double ra, double rb,
|
Chris@16
|
35 coordinate_type const& dx1, coordinate_type const& dy1,
|
Chris@16
|
36 coordinate_type const& dx2, coordinate_type const& dy2,
|
Chris@16
|
37 coordinate_type const& wx, coordinate_type const& wy,
|
Chris@16
|
38 S1 const& s1, S2 const& s2)
|
Chris@16
|
39 {
|
Chris@16
|
40 if(on_segment)
|
Chris@16
|
41 {
|
Chris@16
|
42 // 0 <= ra <= 1 and 0 <= rb <= 1
|
Chris@16
|
43 // Now check if one of them is 0 or 1, these are "touch" cases
|
Chris@16
|
44 bool a = math::equals(ra, 0.0) || math::equals(ra, 1.0);
|
Chris@16
|
45 bool b = math::equals(rb, 0.0) || math::equals(rb, 1.0);
|
Chris@16
|
46 if (a && b)
|
Chris@16
|
47 {
|
Chris@16
|
48 // Touch boundary/boundary: i-i == -1, i-b == -1, b-b == 0
|
Chris@16
|
49 // Opposite: if both are equal they touch in opposite direction
|
Chris@16
|
50 return de9im_segment(ra,rb,
|
Chris@16
|
51 -1, -1, 1,
|
Chris@16
|
52 -1, 0, 0,
|
Chris@16
|
53 1, 0, 2, false, math::equals(ra,rb));
|
Chris@16
|
54 }
|
Chris@16
|
55 else if (a || b)
|
Chris@16
|
56 {
|
Chris@16
|
57 // Touch boundary/interior: i-i == -1, i-b == -1 or 0, b-b == -1
|
Chris@16
|
58 int A = a ? 0 : -1;
|
Chris@16
|
59 int B = b ? 0 : -1;
|
Chris@16
|
60 return de9im_segment(ra,rb,
|
Chris@16
|
61 -1, B, 1,
|
Chris@16
|
62 A, -1, 0,
|
Chris@16
|
63 1, 0, 2);
|
Chris@16
|
64 }
|
Chris@16
|
65
|
Chris@16
|
66 // Intersects: i-i == 0, i-b == -1, i-e == 1
|
Chris@16
|
67 return de9im_segment(ra,rb,
|
Chris@16
|
68 0, -1, 1,
|
Chris@16
|
69 -1, -1, 0,
|
Chris@16
|
70 1, 0, 2);
|
Chris@16
|
71 }
|
Chris@16
|
72
|
Chris@16
|
73 // Not on segment, disjoint
|
Chris@16
|
74 return de9im_segment(ra,rb,
|
Chris@16
|
75 -1, -1, 1,
|
Chris@16
|
76 -1, -1, 0,
|
Chris@16
|
77 1, 0, 2);
|
Chris@16
|
78 }
|
Chris@16
|
79
|
Chris@16
|
80 static inline return_type collinear_touch(coordinate_type const& x,
|
Chris@16
|
81 coordinate_type const& y, bool opposite, char)
|
Chris@16
|
82 {
|
Chris@16
|
83 return de9im_segment(0,0,
|
Chris@16
|
84 -1, -1, 1,
|
Chris@16
|
85 -1, 0, 0,
|
Chris@16
|
86 1, 0, 2,
|
Chris@16
|
87 true, opposite);
|
Chris@16
|
88 }
|
Chris@16
|
89
|
Chris@16
|
90 template <typename S>
|
Chris@16
|
91 static inline return_type collinear_interior_boundary_intersect(S const& s,
|
Chris@16
|
92 bool a_within_b, bool opposite)
|
Chris@16
|
93 {
|
Chris@16
|
94 return a_within_b
|
Chris@16
|
95 ? de9im_segment(0,0,
|
Chris@16
|
96 1, -1, -1,
|
Chris@16
|
97 0, 0, -1,
|
Chris@16
|
98 1, 0, 2,
|
Chris@16
|
99 true, opposite)
|
Chris@16
|
100 : de9im_segment(0,0,
|
Chris@16
|
101 1, 0, 1,
|
Chris@16
|
102 -1, 0, 0,
|
Chris@16
|
103 -1, -1, 2,
|
Chris@16
|
104 true, opposite);
|
Chris@16
|
105 }
|
Chris@16
|
106
|
Chris@16
|
107
|
Chris@16
|
108
|
Chris@16
|
109 static inline return_type collinear_a_in_b(S1 const& s, bool opposite)
|
Chris@16
|
110 {
|
Chris@16
|
111 return de9im_segment(0,0,
|
Chris@16
|
112 1, -1, -1,
|
Chris@16
|
113 0, -1, -1,
|
Chris@16
|
114 1, 0, 2,
|
Chris@16
|
115 true, opposite);
|
Chris@16
|
116 }
|
Chris@16
|
117 static inline return_type collinear_b_in_a(S2 const& s, bool opposite)
|
Chris@16
|
118 {
|
Chris@16
|
119 return de9im_segment(0,0,
|
Chris@16
|
120 1, 0, 1,
|
Chris@16
|
121 -1, -1, 0,
|
Chris@16
|
122 -1, -1, 2,
|
Chris@16
|
123 true, opposite);
|
Chris@16
|
124 }
|
Chris@16
|
125
|
Chris@16
|
126 static inline return_type collinear_overlaps(
|
Chris@16
|
127 coordinate_type const& x1, coordinate_type const& y1,
|
Chris@16
|
128 coordinate_type const& x2, coordinate_type const& y2, bool opposite)
|
Chris@16
|
129 {
|
Chris@16
|
130 return de9im_segment(0,0,
|
Chris@16
|
131 1, 0, 1,
|
Chris@16
|
132 0, -1, 0,
|
Chris@16
|
133 1, 0, 2,
|
Chris@16
|
134 true, opposite);
|
Chris@16
|
135 }
|
Chris@16
|
136
|
Chris@16
|
137 static inline return_type segment_equal(S1 const& s, bool opposite)
|
Chris@16
|
138 {
|
Chris@16
|
139 return de9im_segment(0,0,
|
Chris@16
|
140 1, -1, -1,
|
Chris@16
|
141 -1, 0, -1,
|
Chris@16
|
142 -1, -1, 2,
|
Chris@16
|
143 true, opposite);
|
Chris@16
|
144 }
|
Chris@16
|
145
|
Chris@16
|
146 static inline return_type degenerate(S1 const& segment, bool a_degenerate)
|
Chris@16
|
147 {
|
Chris@16
|
148 return a_degenerate
|
Chris@16
|
149 ? de9im_segment(0,0,
|
Chris@16
|
150 0, -1, -1,
|
Chris@16
|
151 -1, -1, -1,
|
Chris@16
|
152 1, 0, 2,
|
Chris@16
|
153 false, false, false, true)
|
Chris@16
|
154 : de9im_segment(0,0,
|
Chris@16
|
155 0, -1, 1,
|
Chris@16
|
156 -1, -1, 0,
|
Chris@16
|
157 -1, -1, 2,
|
Chris@16
|
158 false, false, false, true);
|
Chris@16
|
159 }
|
Chris@16
|
160
|
Chris@16
|
161 };
|
Chris@16
|
162
|
Chris@16
|
163
|
Chris@16
|
164 }} // namespace policies::relate
|
Chris@16
|
165
|
Chris@16
|
166 }} // namespace boost::geometry
|
Chris@16
|
167
|
Chris@16
|
168 #endif // BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_DE9IM_HPP
|