94 inline T
r()
const {
return (*
this)[0];}
95 inline T
x()
const {
return (*
this)[1];}
96 inline T
y()
const {
return (*
this)[2];}
97 inline T
z()
const {
return (*
this)[3];}
98 inline void r(
const T
r) {(*this)[0]=
r;}
99 inline void x(
const T
x) {(*this)[1]=
x;}
100 inline void y(
const T
y) {(*this)[2]=
y;}
101 inline void z(
const T
z) {(*this)[3]=
z;}
114 template <
class ARRAYLIKE3>
122 const T angle = std::sqrt(x*x+y*y+z*z);
126 (*this)[1] =
static_cast<T
>(0.5)*
x;
127 (*this)[2] =
static_cast<T
>(0.5)*
y;
128 (*this)[3] =
static_cast<T
>(0.5)*
z;
132 const T s = (::sin(angle/2))/angle;
133 const T c = ::cos(angle/2);
150 template <
class ARRAYLIKE3>
151 inline void ln(ARRAYLIKE3 &out_ln)
const
153 if (out_ln.size()!=3) out_ln.resize(3);
157 template <
class ARRAYLIKE3>
158 inline ARRAYLIKE3
ln()
const
165 template <
class ARRAYLIKE3>
170 const T K = (xyz_norm<1e-7) ? 2 : 2*::acos(
r())/xyz_norm;
178 template <
class ARRAYLIKE3>
186 template <
class ARRAYLIKE3>
200 this->
r( q1.
r()*q2.
r() - q1.
x()*q2.
x() - q1.
y()*q2.
y() - q1.
z()*q2.
z() );
201 this->
x( q1.
r()*q2.
x() + q2.
r()*q1.
x() + q1.
y()*q2.
z() - q2.
y()*q1.
z() );
202 this->
y( q1.
r()*q2.
y() + q2.
r()*q1.
y() + q1.
z()*q2.
x() - q2.
z()*q1.
x() );
203 this->
z( q1.
r()*q2.
z() + q2.
r()*q1.
z() + q1.
x()*q2.
y() - q2.
x()*q1.
y() );
209 void rotatePoint(
const double lx,
const double ly,
const double lz,
double &gx,
double &gy,
double &gz )
const
211 const double t2 =
r()*
x();
const double t3 =
r()*
y();
const double t4 =
r()*
z();
const double t5 =-
x()*
x();
const double t6 =
x()*
y();
212 const double t7 =
x()*
z();
const double t8 =-
y()*
y();
const double t9 =
y()*
z();
const double t10=-
z()*
z();
213 gx = 2*((t8+ t10)*lx+(t6 - t4)*ly+(t3+t7)*lz)+lx;
214 gy = 2*((t4+ t6)*lx+(t5 +t10)*ly+(t9-t2)*lz)+ly;
215 gz = 2*((t7- t3)*lx+(t2 + t9)*ly+(t5+t8)*lz)+lz;
220 void inverseRotatePoint(
const double lx,
const double ly,
const double lz,
double &gx,
double &gy,
double &gz )
const
222 const double t2 =-
r()*
x();
const double t3 =-
r()*
y();
const double t4 =-
r()*
z();
const double t5 =-
x()*
x();
const double t6 =
x()*
y();
223 const double t7 =
x()*
z();
const double t8 =-
y()*
y();
const double t9 =
y()*
z();
const double t10=-
z()*
z();
224 gx = 2*((t8+ t10)*lx+(t6 - t4)*ly+(t3+t7)*lz)+lx;
225 gy = 2*((t4+ t6)*lx+(t5 +t10)*ly+(t9-t2)*lz)+ly;
226 gz = 2*((t7- t3)*lx+(t2 + t9)*ly+(t5+t8)*lz)+lz;
230 inline double normSqr()
const {
239 const T qq = 1.0/std::sqrt(
normSqr() );
240 for (
unsigned int i=0;i<4;i++)
247 template <
class MATRIXLIKE>
250 const T n = 1.0/std::pow(
normSqr(),T(1.5));
252 J.get_unsafe(0,0)=
x()*
x()+
y()*
y()+
z()*
z();
253 J.get_unsafe(0,1)=-
r()*
x();
254 J.get_unsafe(0,2)=-
r()*
y();
255 J.get_unsafe(0,3)=-
r()*
z();
257 J.get_unsafe(1,0)=-
x()*
r();
258 J.get_unsafe(1,1)=
r()*
r()+
y()*
y()+
z()*
z();
259 J.get_unsafe(1,2)=-
x()*
y();
260 J.get_unsafe(1,3)=-
x()*
z();
262 J.get_unsafe(2,0)=-
y()*
r();
263 J.get_unsafe(2,1)=-
y()*
x();
264 J.get_unsafe(2,2)=
r()*
r()+
x()*
x()+
z()*
z();
265 J.get_unsafe(2,3)=-
y()*
z();
267 J.get_unsafe(3,0)=-
z()*
r();
268 J.get_unsafe(3,1)=-
z()*
x();
269 J.get_unsafe(3,2)=-
z()*
y();
270 J.get_unsafe(3,3)=
r()*
r()+
x()*
x()+
y()*
y();
277 template <
class MATRIXLIKE>
281 J.get_unsafe(0,0)=
r(); J.get_unsafe(0,1)=-
x(); J.get_unsafe(0,2)=-
y(); J.get_unsafe(0,3)=-
z();
282 J.get_unsafe(1,0)=
x(); J.get_unsafe(1,1)=
r(); J.get_unsafe(1,2)=-
z(); J.get_unsafe(1,3)=
y();
283 J.get_unsafe(2,0)=
y(); J.get_unsafe(2,1)=
z(); J.get_unsafe(2,2)=
r(); J.get_unsafe(2,3)=-
x();
284 J.get_unsafe(3,0)=
z(); J.get_unsafe(3,1)=-
y(); J.get_unsafe(3,2)=
x(); J.get_unsafe(3,3)=
r();
296 template <
class MATRIXLIKE>
304 template <
class MATRIXLIKE>
307 M.get_unsafe(0,0)=
r()*
r()+
x()*
x()-
y()*
y()-
z()*
z(); M.get_unsafe(0,1)=2*(
x()*
y() -
r()*
z()); M.get_unsafe(0,2)=2*(
z()*
x()+
r()*
y());
308 M.get_unsafe(1,0)=2*(
x()*
y()+
r()*
z()); M.get_unsafe(1,1)=
r()*
r()-
x()*
x()+
y()*
y()-
z()*
z(); M.get_unsafe(1,2)=2*(
y()*
z()-
r()*
x());
309 M.get_unsafe(2,0)=2*(
z()*
x()-
r()*
y()); M.get_unsafe(2,1)=2*(
y()*
z()+
r()*
x()); M.get_unsafe(2,2)=
r()*
r()-
x()*
x()-
y()*
y()+
z()*
z();
334 inline void rpy(T &roll, T &pitch, T &yaw)
const
336 rpy_and_jacobian(roll,pitch,yaw,static_cast<mrpt::math::CMatrixDouble*>(NULL));
344 template <
class MATRIXLIKE>
345 void rpy_and_jacobian(T &roll, T &pitch, T &yaw, MATRIXLIKE *out_dr_dq = NULL,
bool resize_out_dr_dq_to3x4 =
true )
const
350 if (out_dr_dq && resize_out_dr_dq_to3x4)
351 out_dr_dq->setSize(3,4);
352 const T discr =
r()*
y()-
x()*
z();
353 if (fabs(discr)>0.49999)
356 yaw =-2*atan2(
x(),
r());
360 out_dr_dq->get_unsafe(0,0) = +2/
x();
361 out_dr_dq->get_unsafe(0,2) = -2*
r()/(
x()*
x());
364 else if (discr<-0.49999)
367 yaw =+2*atan2(
x(),
r());
371 out_dr_dq->get_unsafe(0,0) = -2/
x();
372 out_dr_dq->get_unsafe(0,2) = +2*
r()/(
x()*
x());
377 yaw = ::atan2( 2*(
r()*
z()+
x()*
y()), 1-2*(
y()*
y()+
z()*
z()) );
378 pitch = ::asin ( 2*discr );
379 roll = ::atan2( 2*(
r()*
x()+
y()*
z()), 1-2*(
x()*
x()+
y()*
y()) );
382 const double val1=(2*
x()*
x() + 2*
y()*
y() - 1);
383 const double val12=
square(val1);
384 const double val2=(2*
r()*
x() + 2*
y()*
z());
385 const double val22=
square(val2);
386 const double xy2 = 2*
x()*
y();
387 const double rz2 = 2*
r()*
z();
388 const double ry2 = 2*
r()*
y();
389 const double val3 = (2*
y()*
y() + 2*
z()*
z() - 1);
390 const double val4 = ((
square(rz2 + xy2)/
square(val3) + 1)*val3);
391 const double val5 = (4*(rz2 + xy2))/
square(val3);
392 const double val6 = 1.0/(
square(rz2 + xy2)/
square(val3) + 1);
393 const double val7 = 2.0/ sqrt(1 -
square(ry2 - 2*
x()*
z()));
394 const double val8 = (val22/val12 + 1);
395 const double val9 = -2.0/val8;
397 out_dr_dq->get_unsafe(0,0) = -2*
z()/val4;
398 out_dr_dq->get_unsafe(0,1) = -2*
y()/val4;
399 out_dr_dq->get_unsafe(0,2) = -(2*
x()/val3 -
y()*val5)*val6 ;
400 out_dr_dq->get_unsafe(0,3) = -(2*
r()/val3 -
z()*val5)*val6;
402 out_dr_dq->get_unsafe(1,0) =
y()*val7 ;
403 out_dr_dq->get_unsafe(1,1) = -
z()*val7 ;
404 out_dr_dq->get_unsafe(1,2) =
r()*val7 ;
405 out_dr_dq->get_unsafe(1,3) = -
x()*val7 ;
407 out_dr_dq->get_unsafe(2,0) = val9*
x()/val1 ;
408 out_dr_dq->get_unsafe(2,1) = val9*(
r()/val1 - (2*
x()*val2)/val12) ;
409 out_dr_dq->get_unsafe(2,2) = val9*(
z()/val1 - (2*
y()*val2)/val12) ;
410 out_dr_dq->get_unsafe(2,3) = val9*
y()/val1 ;