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/Kernel_23/include/CGAL/Iso_rectangle_2.h $
11 // $Id: Iso_rectangle_2.h 4e519a3 2021-05-05T13:15:37+02:00 Sébastien Loriot
12 // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
13 //
14 //
15 // Author(s)     : Andreas Fabri
16 
17 #ifndef CGAL_ISO_RECTANGLE_2_H
18 #define CGAL_ISO_RECTANGLE_2_H
19 
20 #include <CGAL/assertions.h>
21 #include <boost/type_traits/is_same.hpp>
22 #include <CGAL/Kernel/Return_base_tag.h>
23 #include <CGAL/Bbox_2.h>
24 #include <CGAL/Dimension.h>
25 
26 namespace CGAL {
27 
28 template <class R_>
29 class Iso_rectangle_2 : public R_::Kernel_base::Iso_rectangle_2
30 {
31   typedef typename R_::RT                    RT;
32   typedef typename R_::FT                    FT;
33   typedef typename R_::Point_2               Point_2;
34   typedef typename R_::Aff_transformation_2  Aff_transformation_2;
35 
36   typedef Iso_rectangle_2                    Self;
37   CGAL_static_assertion((boost::is_same<Self, typename R_::Iso_rectangle_2>::value));
38 
39 public:
40 
41   typedef Dimension_tag<2>  Ambient_dimension;
42   typedef Dimension_tag<2>  Feature_dimension;
43 
44   typedef typename R_::Kernel_base::Iso_rectangle_2  Rep;
45 
rep()46   const Rep& rep() const
47   {
48     return *this;
49   }
50 
rep()51   Rep& rep()
52   {
53     return *this;
54   }
55 
56   typedef  R_   R;
57 
Iso_rectangle_2()58   Iso_rectangle_2() {}
59 
Iso_rectangle_2(const Rep & r)60   Iso_rectangle_2(const Rep& r)
61     : Rep(r) {}
62 
Iso_rectangle_2(const Point_2 & p,const Point_2 & q,int)63   Iso_rectangle_2(const Point_2 &p, const Point_2 &q, int)
64     : Rep(typename R::Construct_iso_rectangle_2()(Return_base_tag(), p, q, 0)) {}
65 
Iso_rectangle_2(const Point_2 & p,const Point_2 & q)66   Iso_rectangle_2(const Point_2 &p, const Point_2 &q)
67     : Rep(typename R::Construct_iso_rectangle_2()(Return_base_tag(), p, q)) {}
68 
Iso_rectangle_2(const Point_2 & left,const Point_2 & right,const Point_2 & bottom,const Point_2 & top)69   Iso_rectangle_2(const Point_2 &left, const Point_2 &right,
70                   const Point_2 &bottom, const Point_2 &top)
71     : Rep(typename R::Construct_iso_rectangle_2()(Return_base_tag(), left, right, bottom, top)) {}
72 
Iso_rectangle_2(const RT & min_hx,const RT & min_hy,const RT & max_hx,const RT & max_hy)73   Iso_rectangle_2(const RT& min_hx, const RT& min_hy,
74                   const RT& max_hx, const RT& max_hy)
75     : Rep(typename R::Construct_iso_rectangle_2()(Return_base_tag(), min_hx, min_hy, max_hx, max_hy)) {}
76 
Iso_rectangle_2(const RT & min_hx,const RT & min_hy,const RT & max_hx,const RT & max_hy,const RT & hw)77   Iso_rectangle_2(const RT& min_hx, const RT& min_hy,
78                   const RT& max_hx, const RT& max_hy, const RT& hw)
79     : Rep(typename R::Construct_iso_rectangle_2()(Return_base_tag(), min_hx, min_hy, max_hx, max_hy, hw)) {}
80 
Iso_rectangle_2(const Bbox_2 & bbox)81   Iso_rectangle_2(const Bbox_2& bbox)
82     : Rep(typename R::Construct_iso_rectangle_2()(Return_base_tag(), bbox.xmin(), bbox.ymin(), bbox.xmax(), bbox.ymax())) {}
83 
decltype(auto)84   decltype(auto)
85   min BOOST_PREVENT_MACRO_SUBSTITUTION () const
86   {
87     return R().construct_min_vertex_2_object()(*this);
88   }
89 
decltype(auto)90   decltype(auto)
91   max BOOST_PREVENT_MACRO_SUBSTITUTION () const
92   {
93     return R().construct_max_vertex_2_object()(*this);
94   }
95 
96   bool
97   operator==(const Iso_rectangle_2 &i) const
98   {
99     return R().equal_2_object()(*this, i);
100   }
101 
102   bool
103   operator!=(const Iso_rectangle_2 &i) const
104   {
105     return ! (*this == i);
106   }
107 
108 
109   decltype(auto)
vertex(int i)110   vertex(int i) const
111   {
112     return R().construct_vertex_2_object()(*this,i);
113   }
114 
decltype(auto)115   decltype(auto)
116   operator[](int i) const
117   {
118     return R().construct_vertex_2_object()(*this,i);
119   }
120 
121   decltype(auto)
xmin()122   xmin() const
123   {
124     return R().compute_xmin_2_object()(*this);
125   }
126 
127   decltype(auto)
xmax()128   xmax() const
129   {
130     return R().compute_xmax_2_object()(*this);
131   }
132 
133   decltype(auto)
ymin()134   ymin() const
135   {
136     return R().compute_ymin_2_object()(*this);
137   }
138 
139   decltype(auto)
ymax()140   ymax() const
141   {
142     return R().compute_ymax_2_object()(*this);
143   }
144 
145   decltype(auto)
min_coord(int i)146   min_coord(int i) const
147   {
148     CGAL_kernel_precondition( i == 0 || i == 1 );
149     if (i == 0)
150       return xmin();
151     else
152       return ymin();
153   }
154 
155   decltype(auto)
max_coord(int i)156   max_coord(int i) const
157   {
158     CGAL_kernel_precondition( i == 0 || i == 1 );
159     if (i == 0)
160       return xmax();
161     else
162       return ymax();
163   }
164 
165   FT
area()166   area() const
167   {
168     return R().compute_area_2_object()(*this);
169   }
170 
171 
172   bool
has_on_boundary(const Point_2 & p)173   has_on_boundary(const Point_2 &p) const
174   {
175     return R().has_on_boundary_2_object()(*this,p);
176   }
177 
178 
179   bool
has_on_bounded_side(const Point_2 & p)180   has_on_bounded_side(const Point_2 &p) const
181   {
182     return R().has_on_bounded_side_2_object()(*this,p);
183   }
184 
185 
186   bool
has_on_unbounded_side(const Point_2 & p)187   has_on_unbounded_side(const Point_2 &p) const
188   {
189     return R().has_on_unbounded_side_2_object()(*this,p);
190   }
191 
192   Bounded_side
bounded_side(const Point_2 & p)193   bounded_side(const Point_2 &p) const
194   {
195     return R().bounded_side_2_object()(*this,p);
196   }
197 
198 
199   bool
is_degenerate()200   is_degenerate() const
201   {
202     return R().is_degenerate_2_object()(*this);
203   }
204 
205   Bbox_2
bbox()206   bbox() const
207   {
208     return R().construct_bbox_2_object()(*this);
209   }
210 
transform(const Aff_transformation_2 & t)211   Iso_rectangle_2 transform(const Aff_transformation_2 &t) const
212   {
213     // FIXME : We need a precondition like this!!!
214     // CGAL_kernel_precondition(t.is_axis_preserving());
215     return Iso_rectangle_2(t.transform(min  BOOST_PREVENT_MACRO_SUBSTITUTION ()),
216                            t.transform(max  BOOST_PREVENT_MACRO_SUBSTITUTION ()));
217   }
218 };
219 
220 
221 template < class R >
222 std::ostream &
223 operator<<(std::ostream &os, const Iso_rectangle_2<R> &r)
224 {
225   switch(IO::get_mode(os)) {
226   case IO::ASCII :
227     return os << (r.min)() << ' ' << (r.max)();
228   case IO::BINARY :
229     return os << (r.min)() << (r.max)();
230   default:
231     return os << "Iso_rectangle_2(" << (r.min)() << ", " << (r.max)() << ")";
232   }
233 }
234 
235 template < class R >
236 std::istream &
237 operator>>(std::istream &is, Iso_rectangle_2<R> &r)
238 {
239   typename R::Point_2 p, q;
240 
241   is >> p >> q;
242 
243   if (is)
244     r = Iso_rectangle_2<R>(p, q);
245   return is;
246 }
247 
248 } //namespace CGAL
249 
250 #endif // CGAL_ISO_RECTANGLE_2_H
251