Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Segment_2_Segment_2_intersection.h
Go to the documentation of this file.
1 
2 // ======================================================================
3 //
4 // Copyright (c) 2000 The CGAL Consortium
5 
6 // This software and related documentation is part of the Computational
7 // Geometry Algorithms Library (CGAL).
8 // This software and documentation is provided "as-is" and without warranty
9 // of any kind. In no event shall the CGAL Consortium be liable for any
10 // damage of any kind.
11 //
12 // Every use of CGAL requires a license.
13 //
14 // Academic research and teaching license
15 // - For academic research and teaching purposes, permission to use and copy
16 // the software and its documentation is hereby granted free of charge,
17 // provided that it is not a component of a commercial product, and this
18 // notice appears in all copies of the software and related documentation.
19 //
20 // Commercial licenses
21 // - A commercial license is available through Algorithmic Solutions, who also
22 // markets LEDA (http://www.algorithmic-solutions.de).
23 // - Commercial users may apply for an evaluation license by writing to
24 // Algorithmic Solutions (contact@algorithmic-solutions.com).
25 //
26 // The CGAL Consortium consists of Utrecht University (The Netherlands),
27 // ETH Zurich (Switzerland), Free University of Berlin (Germany),
28 // INRIA Sophia-Antipolis (France), Martin-Luther-University Halle-Wittenberg
29 // (Germany), Max-Planck-Institute Saarbrucken (Germany), RISC Linz (Austria),
30 // and Tel-Aviv University (Israel).
31 //
32 // ----------------------------------------------------------------------
33 //
34 // release : CGAL-2.2
35 // release_date : 2000, September 30
36 //
37 // file : include/CGAL/Segment_2_Segment_2_intersection.h
38 // package : Intersections_2 (2.6.3)
39 // source : intersection_2_1.fw
40 // author(s) : Geert-Jan Giezeman
41 //
42 // coordinator : Saarbruecken
43 //
44 // email : contact@cgal.org
45 // www : http://www.cgal.org
46 //
47 // ======================================================================
48 
49 
50 #ifndef CGAL_SEGMENT_2_SEGMENT_2_INTERSECTION_H
51 #define CGAL_SEGMENT_2_SEGMENT_2_INTERSECTION_H
52 
53 #include <CGAL/Segment_2.h>
54 #include <CGAL/Point_2.h>
55 #include <CGAL/utils.h>
56 #include <CGAL/number_utils.h>
57 
59 
60 template <class R>
62 public:
66  Segment_2<R> const *seg2);
68 
69 #ifndef CGAL_CFG_RETURN_TYPE_BUG_2
71 #else
73 {
74  if (_known)
75  return _result;
76  // The non const this pointer is used to cast away const.
77  _known = true;
78  if (!do_overlap(_seg1->bbox(), _seg2->bbox())) {
79  _result = NO;
80  return _result;
81  }
82  Line_2<R> const &l1 = _seg1->supporting_line();
83  Line_2<R> const &l2 = _seg2->supporting_line();
84  Line_2_Line_2_pair<R> linepair(&l1, &l2);
85  switch ( linepair.intersection_type()) {
87  _result = NO;
88  break;
93  break;
95  {
96  typedef typename R::RT RT;
97  Point_2<R> const &start1 = _seg1->start();
98  Point_2<R> const &end1 = _seg1->end();
99  Point_2<R> const &start2 = _seg2->start();
100  Point_2<R> const &end2 = _seg2->end();
101  Vector_2<R> diff1 = end1-start1;
102  Point_2<R> const *minpt;
103  Point_2<R> const *maxpt;
104  if (CGAL_NTS abs(diff1.x()) > CGAL_NTS abs(diff1.y())) {
105  if (start1.x() < end1.x()) {
106  minpt = &start1;
107  maxpt = &end1;
108  } else {
109  minpt = &end1;
110  maxpt = &start1;
111  }
112  if (start2.x() < end2.x()) {
113  if (start2.x() > minpt->x()) {
114  minpt = &start2;
115  }
116  if (end2.x() < maxpt->x()) {
117  maxpt = &end2;
118  }
119  } else {
120  if (end2.x() > minpt->x()) {
121  minpt = &end2;
122  }
123  if (start2.x() < maxpt->x()) {
124  maxpt = &start2;
125  }
126  }
127  if (maxpt->x() < minpt->x()) {
128  _result = NO;
129  return _result;
130  }
131  if (maxpt->x() == minpt->x()) {
132  _intersection_point = *minpt;
133  _result = POINT;
134  return _result;
135  }
136  _intersection_point = *minpt;
137  _other_point = *maxpt;
138  _result = SEGMENT;
139  return _result;
140  } else {
141  if (start1.y() < end1.y()) {
142  minpt = &start1;
143  maxpt = &end1;
144  } else {
145  minpt = &end1;
146  maxpt = &start1;
147  }
148  if (start2.y() < end2.y()) {
149  if (start2.y() > minpt->y()) {
150  minpt = &start2;
151  }
152  if (end2.y() < maxpt->y()) {
153  maxpt = &end2;
154  }
155  } else {
156  if (end2.y() > minpt->y()) {
157  minpt = &end2;
158  }
159  if (start2.y() < maxpt->y()) {
160  maxpt = &start2;
161  }
162  }
163  if (maxpt->y() < minpt->y()) {
164  _result = NO;
165  return _result;
166  }
167  if (maxpt->y() == minpt->y()) {
168  _intersection_point = *minpt;
169  _result = POINT;
170  return _result;
171  }
172  _intersection_point = *minpt;
173  _other_point = *maxpt;
174  _result = SEGMENT;
175  return _result;
176  }
177  }
178  }
179  return _result;
180 }
181 
182 #endif // CGAL_CFG_RETURN_TYPE_BUG_2
183  bool intersection(Point_2<R> &result) const;
184  bool intersection(Segment_2<R> &result) const;
185 protected:
188  mutable bool _known;
191 };
192 
193 template <class R>
194 inline bool
195 do_intersect(const Segment_2<R> &seg1, const Segment_2<R> &seg2);
196 
197 
199 
200 
201 #include <cassert>
203 
204 namespace CGAL {
205 
206 template <class PT>
208  PT const &p1, PT const &p2, PT const &p3, PT const &p4)
209 {
210  switch (orientation(p1,p2,p3)) {
211  case LEFTTURN:
212  return !rightturn(p3,p4,p2);
213  case RIGHTTURN:
214  return !leftturn(p3,p4,p2);
215  case COLLINEAR:
216  return true;
217  }
218  assert(false);
219  return false;
220 }
221 
222 
223 template <class PT>
225  PT const &p1, PT const &p2, PT const &p3, PT const &p4)
226 {
227  switch (orientation(p1,p2,p3)) {
228  case LEFTTURN:
229  return !leftturn(p1,p2,p4);
230  case RIGHTTURN:
231  return !rightturn(p1,p2,p4);
232  case COLLINEAR:
233  return true;
234  }
235  assert(false);
236  return false;
237 }
238 
239 
240 template <class R>
241 bool
242 do_intersect(const Segment_2<R> &seg1, const Segment_2<R> &seg2)
243 {
244  typename R::Point_2 const & A1 = seg1.source();
245  typename R::Point_2 const & A2 = seg1.target();
246  typename R::Point_2 const & B1 = seg2.source();
247  typename R::Point_2 const & B2 = seg2.target();
248  if (lexicographically_yx_smaller(A1,A2)) {
249  if (lexicographically_yx_smaller(B1,B2)) {
252  return false;
253  } else {
256  return false;
257  }
258  } else {
259  if (lexicographically_yx_smaller(B1,B2)) {
262  return false;
263  } else {
266  return false;
267  }
268  }
269  if (lexicographically_xy_smaller(A1,A2)) {
270  if (lexicographically_xy_smaller(B1,B2)) {
271  switch(compare_lexicographically_xy(A1,B1)) {
272  case SMALLER:
273  switch(compare_lexicographically_xy(A2,B1)) {
274  case SMALLER:
275  return false;
276  case EQUAL:
277  return true;
278  case LARGER:
279  switch(compare_lexicographically_xy(A2,B2)) {
280  case SMALLER:
281  return seg_seg_do_intersect_crossing(A1,A2,B1,B2);
282  case EQUAL:
283  return true;
284  case LARGER:
285  return seg_seg_do_intersect_contained(A1,A2,B1,B2);
286  }
287  }
288  case EQUAL:
289  return true;
290  case LARGER:
291  switch(compare_lexicographically_xy(B2,A1)) {
292  case SMALLER:
293  return false;
294  case EQUAL:
295  return true;
296  case LARGER:
297  switch(compare_lexicographically_xy(B2,A2)) {
298  case SMALLER:
299  return seg_seg_do_intersect_crossing(B1,B2,A1,A2);
300  case EQUAL:
301  return true;
302  case LARGER:
303  return seg_seg_do_intersect_contained(B1,B2,A1,A2);
304  }
305  }
306  }
307  } else {
308  switch(compare_lexicographically_xy(A1,B2)) {
309  case SMALLER:
310  switch(compare_lexicographically_xy(A2,B2)) {
311  case SMALLER:
312  return false;
313  case EQUAL:
314  return true;
315  case LARGER:
316  switch(compare_lexicographically_xy(A2,B1)) {
317  case SMALLER:
318  return seg_seg_do_intersect_crossing(A1,A2,B2,B1);
319  case EQUAL:
320  return true;
321  case LARGER:
322  return seg_seg_do_intersect_contained(A1,A2,B2,B1);
323  }
324  }
325  case EQUAL:
326  return true;
327  case LARGER:
328  switch(compare_lexicographically_xy(B1,A1)) {
329  case SMALLER:
330  return false;
331  case EQUAL:
332  return true;
333  case LARGER:
334  switch(compare_lexicographically_xy(B1,A2)) {
335  case SMALLER:
336  return seg_seg_do_intersect_crossing(B2,B1,A1,A2);
337  case EQUAL:
338  return true;
339  case LARGER:
340  return seg_seg_do_intersect_contained(B2,B1,A1,A2);
341  }
342  }
343  }
344  }
345  } else {
346  if (lexicographically_xy_smaller(B1,B2)) {
347  switch(compare_lexicographically_xy(A2,B1)) {
348  case SMALLER:
349  switch(compare_lexicographically_xy(A1,B1)) {
350  case SMALLER:
351  return false;
352  case EQUAL:
353  return true;
354  case LARGER:
355  switch(compare_lexicographically_xy(A1,B2)) {
356  case SMALLER:
357  return seg_seg_do_intersect_crossing(A2,A1,B1,B2);
358  case EQUAL:
359  return true;
360  case LARGER:
361  return seg_seg_do_intersect_contained(A2,A1,B1,B2);
362  }
363  }
364  case EQUAL:
365  return true;
366  case LARGER:
367  switch(compare_lexicographically_xy(B2,A2)) {
368  case SMALLER:
369  return false;
370  case EQUAL:
371  return true;
372  case LARGER:
373  switch(compare_lexicographically_xy(B2,A1)) {
374  case SMALLER:
375  return seg_seg_do_intersect_crossing(B1,B2,A2,A1);
376  case EQUAL:
377  return true;
378  case LARGER:
379  return seg_seg_do_intersect_contained(B1,B2,A2,A1);
380  }
381  }
382  }
383  } else {
384  switch(compare_lexicographically_xy(A2,B2)) {
385  case SMALLER:
386  switch(compare_lexicographically_xy(A1,B2)) {
387  case SMALLER:
388  return false;
389  case EQUAL:
390  return true;
391  case LARGER:
392  switch(compare_lexicographically_xy(A1,B1)) {
393  case SMALLER:
394  return seg_seg_do_intersect_crossing(A2,A1,B2,B1);
395  case EQUAL:
396  return true;
397  case LARGER:
398  return seg_seg_do_intersect_contained(A2,A1,B2,B1);
399  }
400  }
401  case EQUAL:
402  return true;
403  case LARGER:
404  switch(compare_lexicographically_xy(B1,A2)) {
405  case SMALLER:
406  return false;
407  case EQUAL:
408  return true;
409  case LARGER:
410  switch(compare_lexicographically_xy(B1,A1)) {
411  case SMALLER:
412  return seg_seg_do_intersect_crossing(B2,B1,A2,A1);
413  case EQUAL:
414  return true;
415  case LARGER:
416  return seg_seg_do_intersect_contained(B2,B1,A2,A1);
417  }
418  }
419  }
420  }
421  }
422  assert(false);
423  return false;
424 }
425 
426 } // end namespace CGAL
427 
428 
429 
430 
431 #include <CGAL/Line_2.h>
433 
435 
436 template <class R>
438 {
439  _seg1 = 0;
440  _seg2 = 0;
441  _known = false;
442 }
443 
444 template <class R>
446  Segment_2<R> const *seg1, Segment_2<R> const *seg2)
447 {
448  _seg1 = seg1;
449  _seg2 = seg2;
450  _known = false;
451 }
452 
453 #ifndef CGAL_CFG_RETURN_TYPE_BUG_2
454 template <class R>
457 {
458  if (_known)
459  return _result;
460  // The non const this pointer is used to cast away const.
461  _known = true;
462  if (!do_overlap(_seg1->bbox(), _seg2->bbox())) {
463  _result = NO;
464  return _result;
465  }
466  Line_2<R> const &l1 = _seg1->supporting_line();
467  Line_2<R> const &l2 = _seg2->supporting_line();
468  Line_2_Line_2_pair<R> linepair(&l1, &l2);
469  switch ( linepair.intersection_type()) {
471  _result = NO;
472  break;
474  linepair.intersection(_intersection_point);
475  _result = (_seg1->collinear_has_on(_intersection_point)
476  && _seg2->collinear_has_on(_intersection_point)) ? POINT : NO;
477  break;
479  {
480  typedef typename R::RT RT;
481  Point_2<R> const &start1 = _seg1->start();
482  Point_2<R> const &end1 = _seg1->end();
483  Point_2<R> const &start2 = _seg2->start();
484  Point_2<R> const &end2 = _seg2->end();
485  Vector_2<R> diff1 = end1-start1;
486  Point_2<R> const *minpt;
487  Point_2<R> const *maxpt;
488  if (CGAL_NTS abs(diff1.x()) > CGAL_NTS abs(diff1.y())) {
489  if (start1.x() < end1.x()) {
490  minpt = &start1;
491  maxpt = &end1;
492  } else {
493  minpt = &end1;
494  maxpt = &start1;
495  }
496  if (start2.x() < end2.x()) {
497  if (start2.x() > minpt->x()) {
498  minpt = &start2;
499  }
500  if (end2.x() < maxpt->x()) {
501  maxpt = &end2;
502  }
503  } else {
504  if (end2.x() > minpt->x()) {
505  minpt = &end2;
506  }
507  if (start2.x() < maxpt->x()) {
508  maxpt = &start2;
509  }
510  }
511  if (maxpt->x() < minpt->x()) {
512  _result = NO;
513  return _result;
514  }
515  if (maxpt->x() == minpt->x()) {
516  _intersection_point = *minpt;
517  _result = POINT;
518  return _result;
519  }
520  _intersection_point = *minpt;
521  _other_point = *maxpt;
522  _result = SEGMENT;
523  return _result;
524  } else {
525  if (start1.y() < end1.y()) {
526  minpt = &start1;
527  maxpt = &end1;
528  } else {
529  minpt = &end1;
530  maxpt = &start1;
531  }
532  if (start2.y() < end2.y()) {
533  if (start2.y() > minpt->y()) {
534  minpt = &start2;
535  }
536  if (end2.y() < maxpt->y()) {
537  maxpt = &end2;
538  }
539  } else {
540  if (end2.y() > minpt->y()) {
541  minpt = &end2;
542  }
543  if (start2.y() < maxpt->y()) {
544  maxpt = &start2;
545  }
546  }
547  if (maxpt->y() < minpt->y()) {
548  _result = NO;
549  return _result;
550  }
551  if (maxpt->y() == minpt->y()) {
552  _intersection_point = *minpt;
553  _result = POINT;
554  return _result;
555  }
556  _intersection_point = *minpt;
557  _other_point = *maxpt;
558  _result = SEGMENT;
559  return _result;
560  }
561  }
562  }
563  return _result;
564 }
565 
566 #endif // CGAL_CFG_RETURN_TYPE_BUG_2
567 
568 template <class R>
569 bool
571 {
572  if (!_known)
573  intersection_type();
574  if (_result != POINT)
575  return false;
576  result = _intersection_point;
577  return true;
578 }
579 
580 template <class R>
581 bool
583 {
584  if (!_known)
585  intersection_type();
586  if (_result != SEGMENT)
587  return false;
588  result = Segment_2<R>(_intersection_point, _other_point);
589  return true;
590 }
591 
593 
594 
595 
596 #include <CGAL/Object.h>
597 
599 
600 template <class R>
601 Object
602 intersection(const Segment_2<R> &seg1, const Segment_2<R>&seg2)
603 {
604  typedef Segment_2_Segment_2_pair<R> is_t;
605  is_t ispair(&seg1, &seg2);
606  switch (ispair.intersection_type()) {
607  case is_t::NO:
608  default:
609  return Object();
610  case is_t::POINT: {
611  Point_2<R> pt;
612  ispair.intersection(pt);
613  return Object(new Wrapper< Point_2<R> >(pt));
614  }
615  case is_t::SEGMENT: {
616  Segment_2<R> iseg;
617  ispair.intersection(iseg);
618  return Object(new Wrapper< Segment_2<R> >(iseg));
619  }
620  }
621 }
622 
624 
625 #endif
bool collinear_has_on(const CGAL::Point_2< R > &p) const
Definition: Segment_2.h:120
FT y() const
Definition: Point_2.h:144
CGAL::Line_2< R > supporting_line() const
Definition: Segment_2.h:173
NT p1
Type x() const
Definition: mapbasic.h:208
bool intersection(Point_2< R > &result) const
CGAL_END_NAMESPACE CGAL_BEGIN_NAMESPACE Object intersection(const Line_2< R > &line1, const Line_2< R > &line2)
const Orientation LEFTTURN
Definition: enum.h:66
bool lexicographically_xy_smaller(const Point_2< R > &p, const Point_2< R > &q)
bool do_intersect(const Line_2< R > &p1, const Line_2< R > &p2)
FT x() const
Definition: Point_2.h:139
bool seg_seg_do_intersect_contained(PT const &p1, PT const &p2, PT const &p3, PT const &p4)
CGAL::Point_2< R > target() const
Definition: Segment_2.h:139
Definition: enum.h:96
bool intersection(Point_2< R > &result) const
Type y() const
Definition: mapbasic.h:209
bool do_intersect(const Segment_2< R > &seg1, const Segment_2< R > &seg2)
bool seg_seg_do_intersect_crossing(PT const &p1, PT const &p2, PT const &p3, PT const &p4)
bool rightturn(const Point_2< R > &p, const Point_2< R > &q, const Point_2< R > &r)
CGAL::Point_2< R > source() const
Definition: Segment_2.h:136
bool lexicographically_yx_smaller(const Point_2< R > &p, const Point_2< R > &q)
Orientation orientation(const Point_2< R > &p, const Point_2< R > &q, const Point_2< R > &r)
CGAL::Point_2< R > end() const
Definition: Segment_2.h:133
Definition: enum.h:98
Intersection_results intersection_type() const
bool do_overlap(const Bbox_2 &bb1, const Bbox_2 &bb2)
Comparison_result compare_lexicographically_xy(const Point_2< R > &p, const Point_2< R > &q)
NT abs(const NT &x)
Definition: number_utils.h:130
Definition: enum.h:97
#define CGAL_BEGIN_NAMESPACE
Definition: kdtree_d.h:86
Bbox_2 bbox() const
Definition: Segment_2.h:179
bool leftturn(const Point_2< R > &p, const Point_2< R > &q, const Point_2< R > &r)
#define CGAL_NTS
const Orientation RIGHTTURN
Definition: enum.h:67
const Orientation COLLINEAR
Definition: enum.h:72
#define CGAL_END_NAMESPACE
Definition: kdtree_d.h:87
CGAL::Point_2< R > start() const
Definition: Segment_2.h:130
Intersection_results intersection_type() const
SURF::Vector_2< Real > Point_2
Definition: rfc_basic.h:43