Visual Servoing Platform  version 3.1.0
vpQuaternionVector.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * See the file LICENSE.txt at the root directory of this source
11  * distribution for additional information about the GNU GPL.
12  *
13  * For using ViSP with software that can not be combined with the GNU
14  * GPL, please contact Inria about acquiring a ViSP Professional
15  * Edition License.
16  *
17  * See http://visp.inria.fr for more information.
18  *
19  * This software was developed at:
20  * Inria Rennes - Bretagne Atlantique
21  * Campus Universitaire de Beaulieu
22  * 35042 Rennes Cedex
23  * France
24  *
25  * If you have questions regarding the use of this file, please contact
26  * Inria at visp@inria.fr
27  *
28  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  *
31  * Description:
32  * Quaternion vector.
33  *
34  * Authors:
35  * Filip Novotny
36  *
37  *****************************************************************************/
38 
39 #include <algorithm>
40 #include <stdio.h>
41 #include <string.h>
42 #include <visp3/core/vpMath.h>
43 #include <visp3/core/vpQuaternionVector.h>
44 
45 // minimum value of sine
46 const double vpQuaternionVector::minimum = 0.0001;
47 
55 
58 
60 vpQuaternionVector::vpQuaternionVector(const double x_, const double y_, const double z_, const double w_)
61  : vpRotationVector(4)
62 {
63  set(x_, y_, z_, w_);
64 }
65 
68 {
69  if (q.size() != 4) {
71  "Cannot construct a quaternion vector from a %d-dimension col vector", q.size()));
72  }
73  for (unsigned int i = 0; i < 4; i++)
74  data[i] = q[i];
75 }
76 
83 
91 
99 void vpQuaternionVector::set(const double qx, const double qy, const double qz, const double qw)
100 {
101  data[0] = qx;
102  data[1] = qy;
103  data[2] = qz;
104  data[3] = qw;
105 }
115 vpQuaternionVector vpQuaternionVector::buildFrom(const double qx, const double qy, const double qz, const double qw)
116 {
117  set(qx, qy, qz, qw);
118  return *this;
119 }
120 
128 {
129  vpRotationMatrix R(tu);
130  buildFrom(R);
131 
132  return *this;
133 }
142 {
143  return vpQuaternionVector(x() + q.x(), y() + q.y(), z() + q.z(), w() + q.w());
144 }
153 {
154  return vpQuaternionVector(x() - q.x(), y() - q.y(), z() - q.z(), w() - q.w());
155 }
156 
159 
162 {
163  return vpQuaternionVector(l * x(), l * y(), l * z(), l * w());
164 }
165 
168 {
169  return vpQuaternionVector(w() * rq.x() + x() * rq.w() + y() * rq.z() - z() * rq.y(),
170  w() * rq.y() + y() * rq.w() + z() * rq.x() - x() * rq.z(),
171  w() * rq.z() + z() * rq.w() + x() * rq.y() - y() * rq.x(),
172  w() * rq.w() - x() * rq.x() - y() * rq.y() - z() * rq.z());
173 }
174 
177 {
178  if (vpMath::nul(l, std::numeric_limits<double>::epsilon())) {
179  throw vpException(vpException::fatalError, "Division by scalar l==0 !");
180  }
181 
182  return vpQuaternionVector(x() / l, y() / l, z() / l, w() / l);
183 }
209 {
210  if (q.size() != 4) {
211  throw(vpException(vpException::dimensionError, "Cannot set a quaternion vector from a %d-dimension col vector",
212  q.size()));
213  }
214  for (unsigned int i = 0; i < 4; i++)
215  data[i] = q[i];
216 
217  return *this;
218 }
219 
226 {
227  vpThetaUVector tu(R);
228  vpColVector u;
229  double theta;
230  tu.extract(theta, u);
231 
232  theta *= 0.5;
233 
234  double sinTheta_2 = sin(theta);
235  set(u[0] * sinTheta_2, u[1] * sinTheta_2, u[2] * sinTheta_2, cos(theta));
236  return *this;
237 }
238 
245 
252 {
253  vpQuaternionVector q_inv;
254 
255  double mag_square = w() * w() + x() * x() + y() * y() + z() * z();
256  if (!vpMath::nul(mag_square, std::numeric_limits<double>::epsilon())) {
257  q_inv = this->conjugate() / mag_square;
258  } else {
259  std::cerr << "The current quaternion is null ! The inverse cannot be computed !" << std::endl;
260  }
261 
262  return q_inv;
263 }
264 
270 double vpQuaternionVector::magnitude() const { return sqrt(w() * w() + x() * x() + y() * y() + z() * z()); }
271 
276 {
277  double mag = magnitude();
278  if (!vpMath::nul(mag, std::numeric_limits<double>::epsilon())) {
279  set(x() / mag, y() / mag, z() / mag, w() / mag);
280  }
281 }
282 
284 double vpQuaternionVector::x() const { return data[0]; }
286 double vpQuaternionVector::y() const { return data[1]; }
288 double vpQuaternionVector::z() const { return data[2]; }
290 double vpQuaternionVector::w() const { return data[3]; }
Implementation of a generic rotation vector.
void set(const double x, const double y, const double z, const double w)
void extract(double &theta, vpColVector &u) const
double z() const
Returns z-component of the quaternion.
vpQuaternionVector conjugate() const
error that can be emited by ViSP classes.
Definition: vpException.h:71
double * data
Address of the first element of the data array.
Definition: vpArray2D.h:84
vpQuaternionVector buildFrom(const double qx, const double qy, const double qz, const double qw)
unsigned int size() const
Return the number of elements of the 2D array.
Definition: vpArray2D.h:158
Implementation of a rotation matrix and operations on such kind of matrices.
vpQuaternionVector inverse() const
static bool nul(double x, double s=0.001)
Definition: vpMath.h:281
vpQuaternionVector operator+(const vpQuaternionVector &q) const
Implementation of a rotation vector as quaternion angle minimal representation.
double y() const
Returns y-component of the quaternion.
vpQuaternionVector operator/(const double l) const
Division by scalar. Returns a quaternion defined by (x/l,y/l,z/l,w/l).
double x() const
Returns x-component of the quaternion.
vpQuaternionVector & operator=(const vpColVector &q)
Implementation of column vector and the associated operations.
Definition: vpColVector.h:72
vpQuaternionVector operator-() const
Negate operator. Returns a quaternion defined by (-x,-y,-z-,-w).
vpQuaternionVector operator*(const double l) const
Multiplication by scalar. Returns a quaternion defined by (lx,ly,lz,lw).
double w() const
Returns w-component of the quaternion.
Implementation of a rotation vector as axis-angle minimal representation.