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/Cartesian_kernel/include/CGAL/Cartesian/Tetrahedron_3.h $
11 // $Id: Tetrahedron_3.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 //
15 // Author(s) : Andreas Fabri
16
17 #ifndef CGAL_CARTESIAN_TETRAHEDRON_3_H
18 #define CGAL_CARTESIAN_TETRAHEDRON_3_H
19
20 #include <CGAL/array.h>
21 #include <CGAL/Handle_for.h>
22 #include <CGAL/enum.h>
23 #include <vector>
24 #include <functional>
25
26 namespace CGAL {
27
28 template <class R_>
29 class TetrahedronC3
30 {
31 typedef typename R_::FT FT;
32 typedef typename R_::Point_3 Point_3;
33 typedef typename R_::Plane_3 Plane_3;
34 typedef typename R_::Tetrahedron_3 Tetrahedron_3;
35
36 typedef std::array<Point_3, 4> Rep;
37 typedef typename R_::template Handle<Rep>::type Base;
38
39 Base base;
40
41 public:
42 typedef R_ R;
43
TetrahedronC3()44 TetrahedronC3() {}
45
TetrahedronC3(const Point_3 & p,const Point_3 & q,const Point_3 & r,const Point_3 & s)46 TetrahedronC3(const Point_3 &p, const Point_3 &q, const Point_3 &r,
47 const Point_3 &s)
48 : base(CGAL::make_array(p, q, r, s)) {}
49
50 const Point_3 & vertex(int i) const;
51 const Point_3 & operator[](int i) const;
52
53 typename R::Boolean operator==(const TetrahedronC3 &t) const;
54 typename R::Boolean operator!=(const TetrahedronC3 &t) const;
55
56 typename R::Orientation orientation() const;
57 typename R::Oriented_side oriented_side(const Point_3 &p) const;
58 typename R::Bounded_side bounded_side(const Point_3 &p) const;
59
60 typename R::Boolean has_on_boundary(const Point_3 &p) const;
61 typename R::Boolean has_on_positive_side(const Point_3 &p) const;
62 typename R::Boolean has_on_negative_side(const Point_3 &p) const;
63 typename R::Boolean has_on_bounded_side(const Point_3 &p) const;
64 typename R::Boolean has_on_unbounded_side(const Point_3 &p) const;
65
66 typename R::Boolean is_degenerate() const;
67 };
68
69 template < class R >
70 typename R::Boolean
71 TetrahedronC3<R>::
72 operator==(const TetrahedronC3<R> &t) const
73 {
74 if (CGAL::identical(base, t.base))
75 return true;
76 if (orientation() != t.orientation())
77 return false;
78
79 std::vector< Point_3 > V1;
80 std::vector< Point_3 > V2;
81 typename std::vector< Point_3 >::iterator uniq_end1;
82 typename std::vector< Point_3 >::iterator uniq_end2;
83 int k;
84 for ( k=0; k < 4; k++) V1.push_back( vertex(k));
85 for ( k=0; k < 4; k++) V2.push_back( t.vertex(k));
86 typename R::Less_xyz_3 Less_object = R().less_xyz_3_object();
87 std::sort(V1.begin(), V1.end(), Less_object);
88 std::sort(V2.begin(), V2.end(), Less_object);
89 uniq_end1 = std::unique( V1.begin(), V1.end());
90 uniq_end2 = std::unique( V2.begin(), V2.end());
91 V1.erase( uniq_end1, V1.end());
92 V2.erase( uniq_end2, V2.end());
93 return V1 == V2;
94 }
95
96 template < class R >
97 inline
98 typename R::Boolean
99 TetrahedronC3<R>::
100 operator!=(const TetrahedronC3<R> &t) const
101 {
102 return !(*this == t);
103 }
104
105 template < class R >
106 const typename TetrahedronC3<R>::Point_3 &
107 TetrahedronC3<R>::
vertex(int i)108 vertex(int i) const
109 {
110 if (i<0) i=(i%4)+4;
111 else if (i>3) i=i%4;
112 switch (i)
113 {
114 case 0: return get_pointee_or_identity(base)[0];
115 case 1: return get_pointee_or_identity(base)[1];
116 case 2: return get_pointee_or_identity(base)[2];
117 default: return get_pointee_or_identity(base)[3];
118 }
119 }
120
121 template < class R >
122 inline
123 const typename TetrahedronC3<R>::Point_3 &
124 TetrahedronC3<R>::
125 operator[](int i) const
126 {
127 return vertex(i);
128 }
129
130 template < class R >
131 typename R::Orientation
132 TetrahedronC3<R>::
orientation()133 orientation() const
134 {
135 return R().orientation_3_object()(vertex(0), vertex(1),
136 vertex(2), vertex(3));
137 }
138
139 template < class R >
140 typename R::Oriented_side
141 TetrahedronC3<R>::
oriented_side(const typename TetrahedronC3<R>::Point_3 & p)142 oriented_side(const typename TetrahedronC3<R>::Point_3 &p) const
143 {
144 typename R::Orientation o = orientation();
145 if (o != ZERO)
146 return enum_cast<Oriented_side>(bounded_side(p)) * o;
147
148 CGAL_kernel_assertion (!is_degenerate());
149 return ON_ORIENTED_BOUNDARY;
150 }
151
152 template < class R >
153 typename R::Bounded_side
154 TetrahedronC3<R>::
bounded_side(const typename TetrahedronC3<R>::Point_3 & p)155 bounded_side(const typename TetrahedronC3<R>::Point_3 &p) const
156 {
157 return R().bounded_side_3_object()
158 (static_cast<const typename R::Tetrahedron_3&>(*this), p);
159 }
160
161 template < class R >
162 inline
163 typename R::Boolean
has_on_boundary(const typename TetrahedronC3<R>::Point_3 & p)164 TetrahedronC3<R>::has_on_boundary
165 (const typename TetrahedronC3<R>::Point_3 &p) const
166 {
167 return oriented_side(p) == ON_ORIENTED_BOUNDARY;
168 }
169
170 template < class R >
171 inline
172 typename R::Boolean
has_on_positive_side(const typename TetrahedronC3<R>::Point_3 & p)173 TetrahedronC3<R>::has_on_positive_side
174 (const typename TetrahedronC3<R>::Point_3 &p) const
175 {
176 return oriented_side(p) == ON_POSITIVE_SIDE;
177 }
178
179 template < class R >
180 inline
181 typename R::Boolean
has_on_negative_side(const typename TetrahedronC3<R>::Point_3 & p)182 TetrahedronC3<R>::has_on_negative_side
183 (const typename TetrahedronC3<R>::Point_3 &p) const
184 {
185 return oriented_side(p) == ON_NEGATIVE_SIDE;
186 }
187
188 template < class R >
189 inline
190 typename R::Boolean
has_on_bounded_side(const typename TetrahedronC3<R>::Point_3 & p)191 TetrahedronC3<R>::has_on_bounded_side
192 (const typename TetrahedronC3<R>::Point_3 &p) const
193 {
194 return bounded_side(p) == ON_BOUNDED_SIDE;
195 }
196
197 template < class R >
198 inline
199 typename R::Boolean
has_on_unbounded_side(const typename TetrahedronC3<R>::Point_3 & p)200 TetrahedronC3<R>::has_on_unbounded_side
201 (const typename TetrahedronC3<R>::Point_3 &p) const
202 {
203 return bounded_side(p) == ON_UNBOUNDED_SIDE;
204 }
205
206 template < class R >
207 inline
208 typename R::Boolean
is_degenerate()209 TetrahedronC3<R>::is_degenerate() const
210 {
211 return orientation() == COPLANAR;
212 }
213
214 } //namespace CGAL
215
216 #endif // CGAL_CARTESIAN_TETRAHEDRON_3_H
217