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/Direction_3.h $
11 // $Id: Direction_3.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, Stefan Schirra
16
17 #ifndef CGAL_DIRECTION_3_H
18 #define CGAL_DIRECTION_3_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/kernel_assertions.h>
24 #include <CGAL/representation_tags.h>
25 #include <CGAL/Dimension.h>
26 #include <CGAL/IO/io.h>
27
28 namespace CGAL {
29
30 template <class R_>
31 class Direction_3 : public R_::Kernel_base::Direction_3
32 {
33 typedef typename R_::RT RT;
34 typedef typename R_::Vector_3 Vector_3;
35 typedef typename R_::Line_3 Line_3;
36 typedef typename R_::Ray_3 Ray_3;
37 typedef typename R_::Segment_3 Segment_3;
38 typedef typename R_::Aff_transformation_3 Aff_transformation_3;
39
40 typedef Direction_3 Self;
41 CGAL_static_assertion((boost::is_same<Self, typename R_::Direction_3>::value));
42
43 public:
44
45 typedef Dimension_tag<3> Ambient_dimension;
46 typedef Dimension_tag<0> Feature_dimension;
47
48 typedef typename R_::Kernel_base::Direction_3 Rep;
49
rep()50 const Rep& rep() const
51 {
52 return *this;
53 }
54
rep()55 Rep& rep()
56 {
57 return *this;
58 }
59
60 typedef R_ R;
61
Direction_3()62 Direction_3() {}
63
Direction_3(const Rep & d)64 Direction_3(const Rep& d)
65 : Rep(d) {}
66
Direction_3(const Vector_3 & v)67 explicit Direction_3(const Vector_3& v)
68 : Rep(typename R::Construct_direction_3()(Return_base_tag(), v)) {}
69
Direction_3(const Line_3 & l)70 explicit Direction_3(const Line_3& l)
71 : Rep(typename R::Construct_direction_3()(Return_base_tag(), l)) {}
72
Direction_3(const Ray_3 & r)73 explicit Direction_3(const Ray_3& r)
74 : Rep(typename R::Construct_direction_3()(Return_base_tag(), r)) {}
75
Direction_3(const Segment_3 & s)76 explicit Direction_3(const Segment_3& s)
77 : Rep(typename R::Construct_direction_3()(Return_base_tag(), s)) {}
78
Direction_3(const RT & hx,const RT & hy,const RT & hz)79 Direction_3(const RT& hx, const RT& hy, const RT& hz)
80 : Rep(typename R::Construct_direction_3()(Return_base_tag(), hx, hy, hz)) {}
81
transform(const Aff_transformation_3 & t)82 Direction_3 transform(const Aff_transformation_3 &t) const
83 {
84 return t.transform(*this);
85 }
86
87 Direction_3
88 operator-() const
89 {
90 return R().construct_opposite_direction_3_object()(*this);
91 }
92
to_vector()93 Vector_3 to_vector() const
94 {
95 return R().construct_vector_3_object()(*this);
96 }
97
vector()98 Vector_3 vector() const { return to_vector(); }
99
100
101 decltype(auto)
dx()102 dx() const
103 {
104 return R().compute_dx_3_object()(*this);
105 }
106
107 decltype(auto)
dy()108 dy() const
109 {
110 return R().compute_dy_3_object()(*this);
111 }
112
113 decltype(auto)
dz()114 dz() const
115 {
116 return R().compute_dz_3_object()(*this);
117 }
118
119 decltype(auto)
delta(int i)120 delta(int i) const
121 {
122 CGAL_kernel_precondition( i >= 0 && i <= 2 );
123 if (i==0) return dx();
124 if (i==1) return dy();
125 return dz();
126 }
127
128 };
129
130
131 template <class R >
132 std::ostream&
insert(std::ostream & os,const Direction_3<R> & d,const Cartesian_tag &)133 insert(std::ostream& os, const Direction_3<R>& d, const Cartesian_tag&)
134 {
135 typename R::Vector_3 v = d.to_vector();
136 switch(IO::get_mode(os)) {
137 case IO::ASCII :
138 return os << v.x() << ' ' << v.y() << ' ' << v.z();
139 case IO::BINARY :
140 write(os, v.x());
141 write(os, v.y());
142 write(os, v.z());
143 return os;
144 default:
145 os << "DirectionC3(" << v.x() << ", " << v.y() << ", " << v.z() << ")";
146 return os;
147 }
148 }
149
150 template <class R >
151 std::ostream&
insert(std::ostream & os,const Direction_3<R> & d,const Homogeneous_tag &)152 insert(std::ostream& os, const Direction_3<R>& d, const Homogeneous_tag&)
153 {
154 switch(IO::get_mode(os))
155 {
156 case IO::ASCII :
157 return os << d.dx() << ' ' << d.dy() << ' ' << d.dz();
158 case IO::BINARY :
159 write(os, d.dx());
160 write(os, d.dy());
161 write(os, d.dz());
162 return os;
163 default:
164 return os << "DirectionH3(" << d.dx() << ", "
165 << d.dy() << ", "
166 << d.dz() << ')';
167 }
168 }
169
170 template < class R >
171 std::ostream&
172 operator<<(std::ostream& os, const Direction_3<R>& d)
173 {
174 return insert(os, d, typename R::Kernel_tag() );
175 }
176
177
178 template <class R >
179 std::istream&
extract(std::istream & is,Direction_3<R> & d,const Cartesian_tag &)180 extract(std::istream& is, Direction_3<R>& d, const Cartesian_tag&)
181 {
182 typename R::FT x(0), y(0), z(0);
183 switch(IO::get_mode(is)) {
184 case IO::ASCII :
185 is >> IO::iformat(x) >> IO::iformat(y) >> IO::iformat(z);
186 break;
187 case IO::BINARY :
188 read(is, x);
189 read(is, y);
190 read(is, z);
191 break;
192 default:
193 is.setstate(std::ios::failbit);
194 std::cerr << "" << std::endl;
195 std::cerr << "Stream must be in ascii or binary mode" << std::endl;
196 break;
197 }
198 if (is)
199 d = Direction_3<R>(x, y, z);
200 return is;
201 }
202
203 template <class R >
204 std::istream&
extract(std::istream & is,Direction_3<R> & d,const Homogeneous_tag &)205 extract(std::istream& is, Direction_3<R>& d, const Homogeneous_tag&)
206 {
207 typename R::RT x, y, z;
208 switch(IO::get_mode(is))
209 {
210 case IO::ASCII :
211 is >> IO::iformat(x) >> IO::iformat(y) >> IO::iformat(z);
212 break;
213 case IO::BINARY :
214 read(is, x);
215 read(is, y);
216 read(is, z);
217 break;
218 default:
219 is.setstate(std::ios::failbit);
220 std::cerr << "" << std::endl;
221 std::cerr << "Stream must be in ascii or binary mode" << std::endl;
222 break;
223 }
224 if (is)
225 d = Direction_3<R>(x, y, z);
226 return is;
227 }
228
229 template < class R >
230 std::istream&
231 operator>>(std::istream& is, Direction_3<R>& d)
232 {
233 return extract(is, d, typename R::Kernel_tag() );
234 }
235
236 } //namespace CGAL
237
238 #endif // CGAL_DIRECTION_3_H
239