GCC Code Coverage Report


Directory: ./
File: lib/geogram/basic/quaternion.h
Date: 2026-09-07 02:25:23
Exec Total Coverage
Lines: 0 5 0.0%
Functions: 0 0 -%
Branches: 0 2 0.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2000-2022 Inria
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the ALICE Project-Team nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Contact: Bruno Levy
30 *
31 * https://www.inria.fr/fr/bruno-levy
32 *
33 * Inria,
34 * Domaine de Voluceau,
35 * 78150 Le Chesnay - Rocquencourt
36 * FRANCE
37 *
38 */
39
40 #ifndef GEOGRAM_BASIC_QUATERNION
41 #define GEOGRAM_BASIC_QUATERNION
42
43 #include <geogram/basic/common.h>
44 #include <geogram/basic/geometry.h>
45 #include <iostream>
46
47
48 /**
49 * \file geogram/basic/quaternion.h
50 * \brief a class that represents quaternions (eases
51 * manipulation of 3D rotations)
52 */
53
54 namespace GEO {
55
56 /**
57 * \brief Quaternions are useful for representing rotations.
58 * \details This class is inspired by an implementation written
59 * by Paul Rademacher, in his glui library.
60 */
61 class GEOGRAM_API Quaternion {
62 public:
63
64 /**
65 * \brief Constructs a new Quaternion.
66 */
67 Quaternion() : v_(0.0,0.0,0.0), s_(1.0) {
68 }
69
70 /**
71 * \brief Copy-constructs a new Quaternion.
72 * \param[in] rhs the Quaternion to be copied.
73 */
74 Quaternion(const Quaternion& rhs) : v_(rhs.v_), s_(rhs.s_) {
75 }
76
77 /**
78 * \brief Constructs a new quaternion from its coefficients
79 * \param[in] x a coefficient of the quaternion
80 * \param[in] y a coefficient of the quaternion
81 * \param[in] z a coefficient of the quaternion
82 * \param[in] w a coefficient of the quaternion
83 */
84 Quaternion(
85 double x, double y, double z, double w
86 ) : v_(x,y,z), s_(w) {
87 }
88
89 /**
90 * \brief Constructs a new Quaternion from a vector and
91 * a scalar.
92 * \param[in] v a const reference to the vector
93 * \param[in] s the scalalr
94 */
95 Quaternion( const vec3& v, double s ) : v_(v), s_(s) {
96 }
97
98 /**
99 * \brief Copies a Quaternion
100 * \param[in] q the Quaternion to be copied
101 * \return a reference to this Quaternion
102 */
103 Quaternion& operator = ( const Quaternion &q ) {
104 v_ = q.v_ ;
105 s_ = q.s_ ;
106 return *this ;
107 }
108
109 /**
110 * \brief Sets the coefficients of this quaterion
111 * \param[in] v a const reference to the vector components
112 * \param[in] s the scalar component
113 */
114 void set( const vec3& v, double s ) {
115 v_ = v;
116 s_ = s;
117 }
118
119 /**
120 * \brief Displays this Quaternion
121 * \param[in] out a reference to the std::ostream
122 * where this Quaternion should be displayed
123 */
124 void print( std::ostream& out ) const {
125 out << v_.x << " " << v_.y << " " << v_.z << " " << s_ ;
126 }
127
128
129 /**
130 * \brief Converts this Quaternion into a matrix
131 * \return a matrix (mat4) that represents this Quaternion
132 */
133 mat4 to_matrix() const;
134
135 /**
136 * \brief Sets the rotation angle.
137 * \param[in] f the rotation angle
138 */
139 void set_angle( double f ) {
140 vec3 ax = axis();
141 s_ = ::cos(f / 2.0);
142 v_ = ax * ::sin(f / 2.0);
143 }
144
145 /**
146 * \brief Scales the rotation angle.
147 */
148 void scale_angle( double f ) {
149 set_angle( f * angle() );
150 }
151
152 /**
153 * \brief Gets the rotation angle
154 * \return the angle
155 */
156 double angle() const {
157 return 2.0 * acos( s_ ) ;
158 }
159
160 /**
161 * \brief Gets the axis.
162 * \return The axis.
163 */
164 vec3 axis() const;
165
166 /**
167 * \brief Computes the interpolation between two quaternions
168 * \param[in] from a const reference to the first quaternion
169 * \param[in] to a const reference to the second quaternion
170 * \param[in] t time, in [0.0,1.0]
171 * \return a smooth interpolation between \p from and \p to
172 * parameterized by \p t
173 */
174 static Quaternion spherical_interpolation(
175 const Quaternion& from, const Quaternion& to,
176 double t
177 );
178
179 /**
180 * \brief Gets the vector component
181 * \return the vector component
182 * \note the vector part is not the axis of rotation.
183 * The axis of rotation is obtained by calling axis().
184 */
185 const vec3& v() const {
186 return v_;
187 }
188
189 /**
190 * \brief Gets the scalar component
191 * \return the scalar component
192 * \note the scalar component is not the rotation angle.
193 * The rotation angle is obtained by calling angle().
194 */
195 double s() const {
196 return s_;
197 }
198
199 private:
200 vec3 v_ ;
201 double s_ ;
202 } ;
203
204
205 /*************************************************************************/
206
207 /**
208 * \brief Writes a Quaternion to a stream
209 * \param[in,out] out the stream
210 * \param[in] q a const reference to the quaternion
211 * \return a reference to the stream
212 */
213 inline std::ostream& operator<<(std::ostream& out, const Quaternion& q) {
214 q.print(out) ;
215 return out ;
216 }
217
218
219 /**
220 * \brief Reads a Quaternion from a stream
221 * \param[in,out] in the stream
222 * \param[out] q a reference to the quaternion
223 * \return a reference to the stream
224 */
225 inline std::istream& operator>>(std::istream& in, Quaternion& q) {
226 double x=0.0,y=0.0,z=0.0,w=0.0 ;
227 in >> x >> y >> z >> w ;
228 q.set(vec3(x,y,z),w) ;
229 return in ;
230 }
231
232
233 /**
234 * \brief Computes the sum of two Quaternion
235 * \param[in] a a const reference to the first Quaternion
236 * \param[in] b a const reference to the second Quaternion
237 * \return the sum of \p a and \p b
238 */
239 inline Quaternion operator + (const Quaternion& a, const Quaternion& b) {
240 return Quaternion(
241 a.v() + b.v(),
242 a.s() + b.s()
243 ) ;
244 }
245
246 /**
247 * \brief Computes the difference between two Quaternion
248 * \param[in] a a const reference to the first Quaternion
249 * \param[in] b a const reference to the second Quaternion
250 * \return the difference between \p a and \p b
251 */
252 inline Quaternion operator - (const Quaternion& a, const Quaternion& b) {
253 return Quaternion(
254 a.v() - b.v(),
255 a.s() - b.s()
256 ) ;
257 }
258
259 /**
260 * \brief Computes the opposite of a Quaternion
261 * \param[in] a a const reference to the Quaternion
262 * \return the opposite of \p a
263 */
264 inline Quaternion operator - (const Quaternion& a ) {
265 return Quaternion( -1.0 * a.v(), -a.s() );
266 }
267
268 /**
269 * \brief Computes the product of two Quaternion
270 * \param[in] a a const reference to the first Quaternion
271 * \param[in] b a const reference to the second Quaternion
272 * \return the product of \p a and \p b
273 */
274 inline Quaternion operator * ( const Quaternion& a, const Quaternion& b) {
275 return Quaternion(
276 a.s() * b.v() + b.s() * a.v() + cross(a.v(),b.v()),
277 a.s() * b.s() - dot(a.v() , b.v())
278 );
279 }
280
281 /**
282 * \brief Computes the product of a Quaternion and a scalar
283 * \param[in] a a const reference to the Quaternion
284 * \param[in] t the scalar
285 * \return the product of \p a and \p t
286 */
287 inline Quaternion operator * ( const Quaternion& a, double t ) {
288 return Quaternion( t * a.v(), a.s() * t );
289 }
290
291
292 /**
293 * \brief Computes the product of a scalar and a Quaternion
294 * \param[in] t the scalar
295 * \param[in] a a const reference to the second Quaternion
296 * \return the product of \p t and \p a
297 */
298 inline Quaternion operator * ( double t, const Quaternion& a ) {
299 return Quaternion( t * a.v(), a.s() * t );
300 }
301
302 }
303
304 #endif
305