1 // Copyright (c) 1999
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/Homogeneous_kernel/include/CGAL/Homogeneous/CircleH2.h $
11 // $Id: CircleH2.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
12 // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
13 //
14 // Author(s) : Sven Schoenherr
15 // Stefan Schirra
16
17 #ifndef CGAL_CIRCLEH2_H
18 #define CGAL_CIRCLEH2_H
19
20 #include <CGAL/Interval_nt.h>
21 #include <boost/tuple/tuple.hpp>
22
23 namespace CGAL {
24
25 template <class R_>
26 class CircleH2
27 {
28 typedef typename R_::FT FT;
29 typedef typename R_::RT RT;
30 typedef typename R_::Point_2 Point_2;
31
32 typedef boost::tuple<Point_2, FT, Orientation> Rep;
33 typedef typename R_::template Handle<Rep>::type Base;
34
35 Base base;
36
37 public:
38 typedef R_ R;
39
CircleH2()40 CircleH2() {}
41
CircleH2(const Point_2 & p,const Point_2 & q,const Point_2 & r)42 CircleH2(const Point_2& p, const Point_2& q, const Point_2& r)
43 {
44 Orientation o = CGAL::orientation( p, q, r);
45 CGAL_kernel_precondition( o != COLLINEAR);
46
47 Point_2 cp = circumcenter( p, q, r);
48 FT sq_r = squared_distance( p, cp);
49
50 base = Rep(cp, sq_r, o);
51 }
52
CircleH2(const Point_2 & p,const Point_2 & q,const Orientation & o)53 CircleH2(const Point_2& p, const Point_2& q, const Orientation& o)
54 {
55 CGAL_kernel_precondition( o != COLLINEAR);
56
57 if ( p != q)
58 {
59 Point_2 cp = midpoint( p, q);
60 FT sq_r = squared_distance( cp, p);
61 base = Rep(cp, sq_r, o);
62 }
63 else
64 base = Rep(p, FT( 0), o);
65 }
66
CircleH2(const Point_2 & cp,const FT & squared_radius,const Orientation & o)67 CircleH2(const Point_2& cp, const FT& squared_radius,
68 const Orientation& o)
69 {
70 CGAL_precondition( ( ! CGAL_NTS is_negative( squared_radius)) &&
71 ( o != COLLINEAR ) );
72 base = Rep(cp, squared_radius, o);
73 }
74
75 const Point_2 &
76 center() const;
77
78 Orientation
79 orientation() const;
80
81 const FT &
82 squared_radius() const;
83
84 CircleH2<R>
85 opposite() const;
86
87 Oriented_side
88 oriented_side(const Point_2& ) const;
89
90 Bounded_side
91 bounded_side(const Point_2& ) const;
92
93 bool operator==( const CircleH2<R>& ) const;
94 bool operator!=( const CircleH2<R>& ) const;
95 bool has_on_positive_side(const Point_2& ) const;
96 bool has_on_negative_side(const Point_2& ) const;
97 bool has_on_boundary( const Point_2& ) const;
98 bool has_on_bounded_side( const Point_2& ) const;
99 bool has_on_unbounded_side(const Point_2&) const;
100 bool is_degenerate() const;
101
102 // bool oriented_equal( const CircleH2<R>& ) const;
103 // bool unoriented_equal( const CircleH2<R>& ) const;
104 };
105
106 template <class R>
107 inline
108 const typename CircleH2<R>::Point_2 &
center()109 CircleH2<R>::center() const
110 { return get_pointee_or_identity(base).template get<0>(); }
111
112 template <class R>
113 inline
114 const typename CircleH2<R>::FT &
squared_radius()115 CircleH2<R>::squared_radius() const
116 { return get_pointee_or_identity(base).template get<1>(); }
117
118 template <class R>
119 CGAL_KERNEL_INLINE
120 CircleH2<R>
opposite()121 CircleH2<R>::opposite() const
122 {
123 return CircleH2<R>( center(),
124 squared_radius(),
125 CGAL::opposite( orientation() ) );
126 }
127
128 template <class R>
129 inline
130 Orientation
orientation()131 CircleH2<R>::orientation() const
132 { return get_pointee_or_identity(base).template get<2>(); }
133
134 template <class R>
135 CGAL_KERNEL_INLINE
136 Oriented_side
oriented_side(const typename CircleH2<R>::Point_2 & p)137 CircleH2<R>::oriented_side( const typename CircleH2<R>::Point_2& p) const
138 {
139 FT sq_dist = squared_distance( p, center() );
140 FT sq_rad = squared_radius();
141 Comparison_result vgl = CGAL_NTS compare( sq_dist, sq_rad );
142 Oriented_side rel_pos = (vgl == LARGER ) ?
143 ON_NEGATIVE_SIDE :
144 ( (vgl == SMALLER ) ?
145 ON_POSITIVE_SIDE :
146 ON_ORIENTED_BOUNDARY);
147 if (orientation() == POSITIVE)
148 { return rel_pos; }
149 else // NEGATIVE
150 { return CGAL::opposite( rel_pos ); }
151 }
152
153 template <class R>
154 CGAL_KERNEL_INLINE
155 bool
has_on_positive_side(const typename CircleH2<R>::Point_2 & p)156 CircleH2<R>::has_on_positive_side(const typename CircleH2<R>::Point_2& p) const
157 {
158 if ( orientation() == POSITIVE )
159 { return (has_on_bounded_side(p) ); }
160 else
161 { return (has_on_unbounded_side(p) ); }
162 }
163
164 template <class R>
165 CGAL_KERNEL_INLINE
166 bool
has_on_boundary(const typename CircleH2<R>::Point_2 & p)167 CircleH2<R>::has_on_boundary(const typename CircleH2<R>::Point_2& p) const
168 {
169 FT sq_dist = squared_distance( p, center() );
170 FT sq_rad = squared_radius();
171 return ( sq_dist == sq_rad );
172 }
173
174 template <class R>
175 CGAL_KERNEL_INLINE
176 bool
has_on_negative_side(const typename CircleH2<R>::Point_2 & p)177 CircleH2<R>::has_on_negative_side( const typename CircleH2<R>::Point_2&p) const
178 {
179 if ( orientation() == NEGATIVE )
180 {
181 return (has_on_bounded_side(p) );
182 }
183 else
184 {
185 return (has_on_unbounded_side(p) );
186 }
187 }
188
189 template <class R>
190 CGAL_KERNEL_INLINE
191 Bounded_side
bounded_side(const typename CircleH2<R>::Point_2 & p)192 CircleH2<R>::bounded_side(const typename CircleH2<R>::Point_2& p) const
193 {
194 FT sq_dist = squared_distance( p, center() );
195 FT sq_rad = squared_radius();
196 Comparison_result vgl = CGAL_NTS compare( sq_dist, sq_rad );
197 return (vgl == LARGER ) ? ON_UNBOUNDED_SIDE :
198 ( (vgl == SMALLER ) ?
199 ON_BOUNDED_SIDE :
200 ON_BOUNDARY);
201 }
202
203 template <class R>
204 CGAL_KERNEL_INLINE
205 bool
has_on_bounded_side(const typename CircleH2<R>::Point_2 & p)206 CircleH2<R>::has_on_bounded_side(const typename CircleH2<R>::Point_2& p) const
207 {
208 FT sq_dist = squared_distance( p, center() );
209 FT sq_rad = squared_radius();
210 return ( sq_dist < sq_rad );
211 }
212
213 template <class R>
214 CGAL_KERNEL_INLINE
215 bool
has_on_unbounded_side(const typename CircleH2<R>::Point_2 & p)216 CircleH2<R>::has_on_unbounded_side(const typename CircleH2<R>::Point_2&p) const
217 {
218 FT sq_dist = squared_distance( p, center() );
219 FT sq_rad = squared_radius();
220 return ( sq_rad < sq_dist );
221 }
222
223 template <class R>
224 inline
225 bool
is_degenerate()226 CircleH2<R>::is_degenerate() const
227 { return ( squared_radius() == FT(0) ); }
228
229 template <class R>
230 CGAL_KERNEL_INLINE
231 bool
232 CircleH2<R>::operator==(const CircleH2<R>& c) const
233 {
234 return ( center() == c.center() )
235 &&( squared_radius() == c.squared_radius() )
236 &&( orientation() == c.orientation() );
237 }
238
239 template <class R>
240 inline
241 bool
242 CircleH2<R>::operator!=(const CircleH2<R>& c) const
243 { return !(*this == c); }
244
245 } //namespace CGAL
246
247 #endif // CGAL_CIRCLEH2_H
248