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/Triangle_2.h $
11 // $Id: Triangle_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_TRIANGLE_2_H
18 #define CGAL_TRIANGLE_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 #include <CGAL/IO/io.h>
26 
27 namespace CGAL {
28 
29 template <class R_>
30 class Triangle_2 : public R_::Kernel_base::Triangle_2
31 {
32   typedef typename R_::Point_2          Point_2;
33   typedef typename R_::Aff_transformation_2 Aff_transformation_2;
34   typedef typename R_::Kernel_base::Triangle_2  RTriangle_2;
35 
36   typedef Triangle_2                            Self;
37   CGAL_static_assertion((boost::is_same<Self, typename R_::Triangle_2>::value));
38 
39 public:
40 
41   typedef Dimension_tag<2>  Ambient_dimension;
42   typedef Dimension_tag<2>  Feature_dimension;
43 
44   typedef RTriangle_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   typedef typename R::FT               FT;
58 
Triangle_2()59   Triangle_2() {}
60 
Triangle_2(const RTriangle_2 & t)61   Triangle_2(const RTriangle_2& t)
62       : RTriangle_2(t) {}
63 
Triangle_2(const Point_2 & p,const Point_2 & q,const Point_2 & r)64   Triangle_2(const Point_2 &p, const Point_2 &q, const Point_2 &r)
65       : RTriangle_2(typename R::Construct_triangle_2()(Return_base_tag(), p,q,r)) {}
66 
67   FT
area()68   area() const
69   {
70     return R().compute_area_2_object()(vertex(0), vertex(1), vertex(2));
71   }
72 
73   typename R::Orientation
orientation()74   orientation() const
75   {
76     return R().orientation_2_object()(vertex(0), vertex(1), vertex(2));
77   }
78 
79   typename R::Bounded_side
bounded_side(const Point_2 & p)80   bounded_side(const Point_2 &p) const
81   {
82     return R().bounded_side_2_object()(*this,p);
83   }
84 
85   typename R::Oriented_side
oriented_side(const Point_2 & p)86   oriented_side(const Point_2 &p) const
87   {
88     return R().oriented_side_2_object()(*this,p);
89   }
90 
91   typename R::Boolean
92   operator==(const Triangle_2 &t) const
93   {
94     return R().equal_2_object()(*this,t);
95   }
96 
97   typename R::Boolean
98   operator!=(const Triangle_2 &t) const
99   {
100     return !(*this == t);
101   }
102 
103   decltype(auto)
vertex(int i)104   vertex(int i) const
105   {
106     return R().construct_vertex_2_object()(*this,i);
107   }
108 
decltype(auto)109   decltype(auto)
110   operator[](int i) const
111   {
112     return vertex(i);
113   }
114 
115   typename R::Boolean
has_on_bounded_side(const Point_2 & p)116   has_on_bounded_side(const Point_2 &p) const
117   {
118     return bounded_side(p) == ON_BOUNDED_SIDE;
119   }
120 
121   typename R::Boolean
has_on_unbounded_side(const Point_2 & p)122   has_on_unbounded_side(const Point_2 &p) const
123   {
124     return bounded_side(p) == ON_UNBOUNDED_SIDE;
125   }
126 
127   typename R::Boolean
has_on_boundary(const Point_2 & p)128   has_on_boundary(const Point_2 &p) const
129   {
130     return bounded_side(p) == ON_BOUNDARY;
131   }
132 
133   typename R::Boolean
has_on_negative_side(const Point_2 & p)134   has_on_negative_side(const Point_2 &p) const
135   {
136     return oriented_side(p) == ON_NEGATIVE_SIDE;
137   }
138 
139   typename R::Boolean
has_on_positive_side(const Point_2 & p)140   has_on_positive_side(const Point_2 &p) const
141   {
142     return oriented_side(p) == ON_POSITIVE_SIDE;
143   }
144 
145   typename R::Boolean
is_degenerate()146   is_degenerate() const
147   {
148     return R().collinear_2_object()(vertex(0), vertex(1), vertex(2));
149   }
150 
151   Bbox_2
bbox()152   bbox() const
153   {
154     return R().construct_bbox_2_object()(*this);
155   }
156 
157   Triangle_2
opposite()158   opposite() const
159   {
160     return R().construct_opposite_triangle_2_object()(*this);
161   }
162 
163   Triangle_2
transform(const Aff_transformation_2 & t)164   transform(const Aff_transformation_2 &t) const
165   {
166     return Triangle_2(t.transform(vertex(0)),
167                       t.transform(vertex(1)),
168                       t.transform(vertex(2)));
169   }
170 
171 };
172 
173 
174 template < class R >
175 std::ostream &
176 operator<<(std::ostream &os, const Triangle_2<R> &t)
177 {
178     switch(IO::get_mode(os)) {
179     case IO::ASCII :
180         return os << t[0] << ' ' << t[1] << ' ' << t[2];
181     case IO::BINARY :
182         return os << t[0] << t[1]  << t[2];
183     default:
184         return os<< "Triangle_2(" << t[0] << ", "
185                  << t[1] << ", " << t[2] <<")";
186     }
187 }
188 
189 template < class R >
190 std::istream &
191 operator>>(std::istream &is, Triangle_2<R> &t)
192 {
193     typename R::Point_2 p, q, r;
194 
195     is >> p >> q >> r;
196 
197     if (is)
198         t = Triangle_2<R>(p, q, r);
199     return is;
200 }
201 
202 } //namespace CGAL
203 
204 #endif // CGAL_TRIANGLE_2_H
205