KJB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ratpoint.h
Go to the documentation of this file.
1 
6 /*
7  * $Id: ratpoint.h 18278 2014-11-25 01:42:10Z ksimek $
8  */
9 
10 #ifndef QD_CPP_RATPOINT_INCLUDED_IVILAB_UARIZONAVISION
11 #define QD_CPP_RATPOINT_INCLUDED_IVILAB_UARIZONAVISION 1
12 
13 #include <l_cpp/l_exception.h>
14 #include <qd_cpp/pixpoint.h>
15 
16 #include <iosfwd>
17 #include <l_cpp/l_util.h>
18 #include <l/l_sys_lib.h>
19 #include <l/l_sys_io.h>
20 
21 #ifndef UNLIMITED_RATIONAL_PRECISION_QD_CPP_IVILAB
22 #define UNLIMITED_RATIONAL_PRECISION_QD_CPP_IVILAB 0
23 #endif
24 
25 #if UNLIMITED_RATIONAL_PRECISION_QD_CPP_IVILAB
26 #include <boost/multiprecision/cpp_int.hpp>
27 #else
28 #include <boost/rational.hpp>
29 #endif
30 
31 namespace kjb
32 {
33 namespace qd
34 {
35 
36 
38 struct RatPoint
39 {
40 #if UNLIMITED_RATIONAL_PRECISION_QD_CPP_IVILAB
41  typedef boost::multiprecision::cpp_rational Rat;
42 #else
43 #if 0
44  // TOO SMALL
45  typedef boost::rational< PixPoint::Integer > Rat;
46 #else
47  // SOMEWHAT BIGGER
48  typedef boost::rational< long long > Rat;
49 #endif
50 #endif
51 
52  Rat x, y;
53 
55  RatPoint(const PixPoint& p)
56  : x(p.x),
57  y(p.y)
58  {}
59 
61  RatPoint(const Rat& rx, const Rat& ry)
62  : x(rx),
63  y(ry)
64  {}
65 
66 };
67 
68 
70 inline bool operator==(const RatPoint& a, const RatPoint& b)
71 {
72  return a.x == b.x && a.y == b.y;
73 }
74 
76 inline bool operator!=(const RatPoint& a, const RatPoint& b)
77 {
78  return ! (a==b);
79 }
80 
82 inline bool operator<(const RatPoint& a, const RatPoint& b)
83 {
84  return a.y < b.y || (a.y==b.y && a.x < b.x);
85 }
86 
87 
89 inline bool operator<=(const RatPoint& a, const RatPoint& b)
90 {
91  return a==b || a < b;
92 }
93 
94 
96 inline RatPoint operator-(const RatPoint& a, const RatPoint& b)
97 {
98  return RatPoint(a.x - b.x, a.y - b.y);
99 }
100 
101 
103 inline std::ostream& operator<<(std::ostream& s, const RatPoint& p)
104 {
105  s << p.x.numerator();
106  if (p.x.denominator() > 1) s << '/' << p.x.denominator();
107 
108  s << ", " << p.y.numerator();
109  if (p.y.denominator() > 1) s << '/' << p.y.denominator();
110  return s;
111 }
112 
113 
116 {
118 
120  : a(p),
121  b(q)
122  {}
123 };
124 
125 
127 {
128  return s.a == s.b;
129 }
130 
131 
137 inline
139  const PixPoint_line_segment& s,
140  const PixPoint_line_segment& t
141 )
142 {
143  // test if corresponding matrix is singular (zero determinant).
144  return (s.b.x - s.a.x)*(t.a.y - t.b.y) == (s.b.y - s.a.y)*(t.a.x - t.b.x);
145 }
146 
147 
154 bool is_intersecting(
155  const PixPoint_line_segment&,
156  const PixPoint_line_segment&
157 );
158 
159 
160 
162 template <typename LINE_SEGMENT>
164  const LINE_SEGMENT& s,
165  const LINE_SEGMENT& t
166 )
167 {
168  return !is_degenerate(s)
169  && !is_degenerate(t)
170  && are_parallel(s,t)
171  && is_intersecting(s,t)
172  && ( (is_on(s, t.a) && t.a != s.a && t.a != s.b) // t.a inside s
173  || (is_on(s, t.b) && t.b != s.a && t.b != s.b) // t.b inside s
174  || (is_on(t, s.a) && s.a != t.a && s.a != t.b) // s.a inside t
175  || (is_on(t, s.b) && s.b != t.a && s.b != t.b) // s.b inside t
176  || (t.a==s.a && t.b==s.b) // identical
177  || (t.a==s.b && t.b==s.a) // reversed
178  );
179 }
180 
181 
183 template <typename LINE_SEGMENT>
185  const LINE_SEGMENT& s,
186  const LINE_SEGMENT& t,
187  LINE_SEGMENT* shared_continuum
188 )
189 {
190  if ( is_degenerate(s)
191  || is_degenerate(t)
192  || !are_parallel(s,t)
193  || !is_intersecting(s,t)
194  )
195  {
196  return false;
197  }
198 
199  if ((t.a==s.a && t.b==s.b) || (t.a==s.b && t.b==s.a))
200  {
201  *shared_continuum = s;
202  return true;
203  }
204 
205  if (is_on(s, t.a) && t.a != s.a && t.a != s.b) // t.a inside s
206  {
207  if (is_on(t, s.a))
208  {
209  *shared_continuum = LINE_SEGMENT(s.a, t.a);
210  }
211  else if (is_on(t, s.b))
212  {
213  *shared_continuum = LINE_SEGMENT(t.a, s.b);
214  }
215  else
216  {
217  *shared_continuum = t;
218  }
219  return true;
220  }
221 
222  if (is_on(s, t.b) && t.b != s.a && t.b != s.b) // t.b inside s
223  {
224  if (is_on(t, s.a))
225  {
226  *shared_continuum = LINE_SEGMENT(s.a, t.b);
227  }
228  else if (is_on(t, s.b))
229  {
230  *shared_continuum = LINE_SEGMENT(t.b, s.b);
231  }
232  else
233  {
234  *shared_continuum = t;
235  }
236  return true;
237  }
238 
239  if (is_on(t, s.a) && s.a != t.a && s.a != t.b) // s.a inside t
240  {
241  if (is_on(s, t.a))
242  {
243  *shared_continuum = LINE_SEGMENT(s.a, t.a);
244  }
245  else if (is_on(s, t.b))
246  {
247  *shared_continuum = LINE_SEGMENT(s.a, t.b);
248  }
249  else
250  {
251  *shared_continuum = s;
252  }
253  return true;
254  }
255  if (is_on(t, s.b) && s.b != t.a && s.b != t.b) // s.b inside t
256  {
257  if (is_on(s, t.a))
258  {
259  *shared_continuum = LINE_SEGMENT(s.b, t.a);
260  }
261  else if (is_on(s, t.b))
262  {
263  *shared_continuum = LINE_SEGMENT(s.b, t.b);
264  }
265  else
266  {
267  *shared_continuum = s;
268  }
269  return true;
270  }
271  return false; // overlap only at the endpoint, not over a continuum
272 }
273 
274 
275 
278 {
280 
282  : a(p),
283  b(q)
284  {}
285 
287  : a(s.a),
288  b(s.b)
289  {}
290 };
291 
292 
294 {
295  return s.a == s.b;
296 }
297 
298 
299 
300 
302  const RatPoint_line_segment&,
303  const RatPoint&
304 );
305 
306 
307 bool is_on(const RatPoint_line_segment&, const RatPoint&);
308 
309 
310 bool is_intersecting(
311  const RatPoint_line_segment&,
312  const RatPoint_line_segment&
313 );
314 
315 
316 inline
318  const RatPoint_line_segment& s,
319  const RatPoint_line_segment& t
320 )
321 {
322  // test if corresponding matrix is singular (zero determinant).
323  return (s.b.x - s.a.x)*(t.a.y - t.b.y) == (s.b.y - s.a.y)*(t.a.x - t.b.x);
324 }
325 
326 
338 RatPoint line_intersection(
339  const RatPoint_line_segment&,
340  const RatPoint_line_segment&
341 );
342 
343 
356  const RatPoint_line_segment& s,
357  const RatPoint_line_segment& t,
358  RatPoint_line_segment* intersection
359 )
360 {
361  NTX(intersection);
362  if (!is_intersecting(s, t)) return false;
363 
364  if (are_parallel(s, t))
365  {
366  if (!are_sharing_a_continuum(s, t, intersection))
367  {
368  // not a continuum, just an endpoint
369  if (s.a == t.a || s.a == t.b)
370  {
371  intersection -> a = intersection -> b = s.a;
372  }
373  else
374  {
375  KJB(ASSERT(s.b == t.a || s.b == t.b));
376  intersection -> a = intersection -> b = s.b;
377  }
378  }
379  }
380  else
381  {
382  intersection -> a = intersection -> b = line_intersection(s, t);
383  }
384  return true;
385 }
386 
387 
388 #if 0 /* maybe too trivial to commit */
389 
398 inline bool line_intersection(
399  const RatPoint_line_segment& s,
400  const RatPoint& p
401 )
402 {
404  return 0 == triangle_area(s, p);
405 }
406 #endif
407 
408 
409 
410 } // end ns qd
411 } // end ns kjb
412 
413 #endif /* QD_CPP_RATPOINT_INCLUDED_IVILAB_UARIZONAVISION */
bool are_parallel(const PixPoint_line_segment &s, const PixPoint_line_segment &t)
test whether these segments lie on parallel lines or are collinear.
Definition: ratpoint.h:138
PixPoint b
Definition: ratpoint.h:117
#define KJB(x)
Definition: l_util.h:9
RatPoint(const PixPoint &p)
construct from one PixPoint (just copy it)
Definition: ratpoint.h:55
#define KJB_THROW(ex)
Definition: l_exception.h:46
#define ASSERT(condition, message)
Definition: Assert.h:45
basic line segment when endpoints are PixPoints (int coords)
Definition: ratpoint.h:115
#define NTX(a)
Definition: l_exception.h:89
Rat x
Definition: ratpoint.h:52
RatPoint b
Definition: ratpoint.h:279
RatPoint_line_segment(const RatPoint &p, const RatPoint &q)
Definition: ratpoint.h:281
bool is_intersecting(const PixPoint_line_segment &s, const PixPoint_line_segment &t)
Test whether two closed line segments intersect.
Definition: ratpoint.cpp:68
Rat y
Definition: ratpoint.h:52
very basic structure to represent X, Y points with rational coords.
Definition: ratpoint.h:38
closed line segment with rational coords
Definition: ratpoint.h:277
std::ostream & operator<<(std::ostream &o, const Doubly_connected_edge_list &d)
Print a text representation of the DCEL tables (but not the cache)
Definition: dcel.cpp:1270
PixPoint_line_segment(const PixPoint &p, const PixPoint &q)
Definition: ratpoint.h:119
Integer x
x coordinate of the pixel
Definition: pixpoint.h:79
boost::rational< long long > Rat
Definition: ratpoint.h:48
bool is_degenerate(const PixPoint_line_segment &s)
Definition: ratpoint.h:126
bool is_on(const RatPoint_line_segment &s, const RatPoint &c)
test whether a given point lies on a given segment
Definition: ratpoint.cpp:151
bool operator<=(const RatPoint &a, const RatPoint &b)
"row-major" ordering of points
Definition: ratpoint.h:89
bool are_sharing_a_continuum(const LINE_SEGMENT &s, const LINE_SEGMENT &t)
test whether two segments share an infinity of common points
Definition: ratpoint.h:163
RatPoint_line_segment(const PixPoint_line_segment &s)
Definition: ratpoint.h:286
bool operator==(const RatPoint &a, const RatPoint &b)
test equality of two RatPoints, totally unsurprising.
Definition: ratpoint.h:70
RatPoint::Rat triangle_area(const RatPoint_line_segment &s, const RatPoint &apex)
find signed area of triangle defined by segment endpoints and apex.
Definition: ratpoint.cpp:141
RatPoint(const Rat &rx, const Rat &ry)
construct from two rational cartesian coordinates
Definition: ratpoint.h:61
Object thrown when an argument to a function is not acceptable.
Definition: l_exception.h:377
bool operator<(const RatPoint &a, const RatPoint &b)
"row-major" ordering of points
Definition: ratpoint.h:82
bool operator!=(const RatPoint &a, const RatPoint &b)
test inequality of two RatPoints.
Definition: ratpoint.h:76
Representation of an (x,y) pair of pixel coordinates.
Definition: pixpoint.h:57
RatPoint operator-(const RatPoint &a, const RatPoint &b)
subtraction of RatPoints as if they are position vectors
Definition: ratpoint.h:96
RatPoint a
Definition: ratpoint.h:279
PixPoint a
Definition: ratpoint.h:117
bool segment_intersection(const RatPoint_line_segment &s, const RatPoint_line_segment &t, RatPoint_line_segment *intersection)
if segments intersect, return true and compute intersection
Definition: ratpoint.h:355
Support for error handling exception classes in libKJB.
Integer y
y coordinate of the pixel
Definition: pixpoint.h:79
Contains definition for classes PixPath, PixPathAc, DoubleCircle.
RatPoint line_intersection(const RatPoint_line_segment &s, const RatPoint_line_segment &t)
find intersection point of nonparallel lines through these segments
Definition: ratpoint.cpp:84