1 // Copyright (c) 2000
2 // Utrecht University (The Netherlands),
3 // ETH Zurich (Switzerland),
4 // INRIA Sophia-Antipolis (France),
5 // Max-Planck-Institute Saarbruecken (Germany),
6 // and Tel-Aviv University (Israel).  All rights reserved.
7 //
8 // This file is part of CGAL (www.cgal.org)
9 //
10 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Intersections_2/include/CGAL/Intersections_2/Line_2_Ray_2.h $
11 // $Id: Line_2_Ray_2.h e169490 2020-09-30T10:03:30+02:00 Maxime Gimeno
12 // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
13 //
14 //
15 // Author(s)     : Geert-Jan Giezeman
16 
17 
18 #ifndef CGAL_INTERSECTIONS_2_LINE_2_RAY_2_H
19 #define CGAL_INTERSECTIONS_2_LINE_2_RAY_2_H
20 
21 #include <CGAL/Line_2.h>
22 #include <CGAL/Ray_2.h>
23 #include <CGAL/Point_2.h>
24 #include <CGAL/kernel_assertions.h>
25 #include <CGAL/number_utils.h>
26 #include <CGAL/Intersections_2/Line_2_Line_2.h>
27 #include <CGAL/Intersection_traits_2.h>
28 
29 namespace CGAL {
30 
31 namespace Intersections {
32 
33 namespace internal {
34 
35 template <class K>
36 class Ray_2_Line_2_pair {
37 public:
38     enum Intersection_results {NOT_COMPUTED_YET, NO_INTERSECTION, POINT, RAY};
39     typedef typename K::FT FT;
Ray_2_Line_2_pair(typename K::Ray_2 const * ray,typename K::Line_2 const * line)40     Ray_2_Line_2_pair(typename K::Ray_2 const *ray,
41                       typename K::Line_2 const *line)
42       : _ray(ray), _line(line), _result(NOT_COMPUTED_YET),
43         _intersection_point(K().construct_point_2_object()(ORIGIN))
44     {}
45 
46     Intersection_results intersection_type() const;
47 
48     typename K::Point_2   intersection_point() const;
49     typename K::Ray_2     intersection_ray() const;
50 protected:
51     typename K::Ray_2 const *   _ray;
52     typename K::Line_2 const *  _line;
53     mutable Intersection_results    _result;
54     mutable typename K::Point_2         _intersection_point;
55 };
56 
57 template <class K>
do_intersect(const typename K::Ray_2 & p1,const typename K::Line_2 & p2,const K &)58 inline bool do_intersect(
59     const typename K::Ray_2 &p1,
60     const typename K::Line_2 &p2,
61     const K&)
62 {
63     typedef Ray_2_Line_2_pair<K> pair_t;
64     pair_t pair(&p1, &p2);
65     return pair.intersection_type() != pair_t::NO_INTERSECTION;
66 }
67 
68 
69 
70 template <class K>
71 typename Intersection_traits
72 <K, typename K::Ray_2, typename K::Line_2>::result_type
intersection(const typename K::Ray_2 & ray,const typename K::Line_2 & line,const K &)73 intersection(const typename K::Ray_2 &ray,
74              const typename K::Line_2 &line,
75              const K&)
76 {
77     typedef Ray_2_Line_2_pair<K> is_t;
78     is_t ispair(&ray, &line);
79     switch (ispair.intersection_type()) {
80     case is_t::NO_INTERSECTION:
81     default:
82         return intersection_return<typename K::Intersect_2, typename K::Ray_2, typename K::Line_2>();
83     case is_t::POINT:
84         return intersection_return<typename K::Intersect_2, typename K::Ray_2, typename K::Line_2>(ispair.intersection_point());
85     case is_t::RAY:
86         return intersection_return<typename K::Intersect_2, typename K::Ray_2, typename K::Line_2>(ray);
87     }
88 }
89 
90 
91 template <class K>
92 inline
93 typename Intersection_traits
94 <K, typename K::Line_2, typename K::Ray_2>::result_type
intersection(const typename K::Line_2 & line,const typename K::Ray_2 & ray,const K & k)95 intersection(const typename K::Line_2 &line,
96              const typename K::Ray_2 &ray,
97              const K& k)
98 {
99     return internal::intersection(ray, line, k);
100 }
101 
102 
103 template <class K>
do_intersect(const typename K::Line_2 & p1,const typename K::Ray_2 & p2,const K &)104 inline bool do_intersect(
105     const typename K::Line_2 &p1,
106     const typename K::Ray_2 &p2,
107     const K&)
108 {
109     typedef Ray_2_Line_2_pair<K> pair_t;
110     pair_t pair(&p2, &p1);
111     return pair.intersection_type() != pair_t::NO_INTERSECTION;
112 }
113 
114 
115 
116 template <class K>
117 typename Ray_2_Line_2_pair<K>::Intersection_results
intersection_type()118 Ray_2_Line_2_pair<K>::intersection_type() const
119 {
120     if (_result != NOT_COMPUTED_YET)
121         return _result;
122     // The non const this pointer is used to cast away const.
123     const typename K::Line_2 &l1 = _ray->supporting_line();
124     Line_2_Line_2_pair<K> linepair(&l1, _line);
125     switch ( linepair.intersection_type()) {
126     case Line_2_Line_2_pair<K>::NO_INTERSECTION:
127     default:
128         _result = NO_INTERSECTION;
129         break;
130     case Line_2_Line_2_pair<K>::POINT:
131         _intersection_point = linepair.intersection_point();
132         _result = (_ray->collinear_has_on(_intersection_point) ) ?
133                 POINT : NO_INTERSECTION;
134         break;
135     case Line_2_Line_2_pair<K>::LINE:
136         _result = RAY;
137         break;
138     }
139     return _result;
140 }
141 
142 
143 template <class K>
144 typename K::Point_2
intersection_point()145 Ray_2_Line_2_pair<K>::intersection_point() const
146 {
147     if (_result == NOT_COMPUTED_YET)
148         intersection_type();
149     CGAL_kernel_assertion(_result == POINT);
150     return _intersection_point;
151 }
152 
153 template <class K>
154 typename K::Ray_2
intersection_ray()155 Ray_2_Line_2_pair<K>::intersection_ray() const
156 {
157     if (_result == NOT_COMPUTED_YET)
158         intersection_type();
159     CGAL_kernel_assertion(_result == RAY);
160     return *_ray;
161 }
162 
163 } // namespace internal
164 } // namespace Intersections
165 
166 CGAL_INTERSECTION_FUNCTION(Ray_2, Line_2, 2)
167 CGAL_DO_INTERSECT_FUNCTION(Ray_2, Line_2, 2)
168 
169 } //namespace CGAL
170 
171 #endif
172