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