/******************************************************************** * Description: posemath.cc * C++ definitions for pose math library data types and manipulation * functions. * * Derived from a work by Fred Proctor & Will Shackleford * * Author: * License: LGPL Version 2 * System: Linux * * Copyright (c) 2004 All rights reserved. * * Last change: ********************************************************************/ #include "posemath.h" #ifdef PM_PRINT_ERROR #define PM_DEBUG // need debug with printing #endif // place to reference arrays when bounds are exceeded static double noElement = 0.0; static PM_CARTESIAN *noCart = 0; // PM_CARTESIAN class PM_CARTESIAN::PM_CARTESIAN(double _x, double _y, double _z) { x = _x; y = _y; z = _z; } PM_CARTESIAN::PM_CARTESIAN(PM_CONST PM_CYLINDRICAL PM_REF c) { PmCylindrical cyl; PmCartesian cart; toCyl(c, &cyl); pmCylCartConvert(&cyl, &cart); toCart(cart, this); } PM_CARTESIAN::PM_CARTESIAN(PM_CONST PM_SPHERICAL PM_REF s) { PmSpherical sph; PmCartesian cart; toSph(s, &sph); pmSphCartConvert(&sph, &cart); toCart(cart, this); } double &PM_CARTESIAN::operator [] (int n) { switch (n) { case 0: return x; case 1: return y; case 2: return z; default: return noElement; // need to return a double & } } PM_CARTESIAN & PM_CARTESIAN::operator -= (const PM_CARTESIAN &o) { x-=o.x; y-=o.y; z-=o.z; return *this; } PM_CARTESIAN & PM_CARTESIAN::operator += (const PM_CARTESIAN &o) { x+=o.x; y+=o.y; z+=o.z; return *this; } /* const PM_CARTESIAN PM_CARTESIAN::operator+(const PM_CARTESIAN &o) const { PM_CARTESIAN result = *this; result += o; return result; } const PM_CARTESIAN PM_CARTESIAN::operator-(const PM_CARTESIAN &o) const { PM_CARTESIAN result = *this; result -= o; return result; } */ PM_CARTESIAN & PM_CARTESIAN::operator *= (double o) { x*=o; y*=o; z*=o; return *this; } PM_CARTESIAN & PM_CARTESIAN::operator /= (double o) { x/=o; y/=o; z/=o; return *this; } #ifdef INCLUDE_POSEMATH_COPY_CONSTRUCTORS PM_CARTESIAN::PM_CARTESIAN(PM_CCONST PM_CARTESIAN & v) { x = v.x; y = v.y; z = v.z; } #endif // PM_SPHERICAL PM_SPHERICAL::PM_SPHERICAL(double _theta, double _phi, double _r) { theta = _theta; phi = _phi; r = _r; } PM_SPHERICAL::PM_SPHERICAL(PM_CONST PM_CARTESIAN PM_REF v) { PmCartesian cart; PmSpherical sph; toCart(v, &cart); pmCartSphConvert(&cart, &sph); toSph(sph, this); } PM_SPHERICAL::PM_SPHERICAL(PM_CONST PM_CYLINDRICAL PM_REF c) { PmCylindrical cyl; PmSpherical sph; toCyl(c, &cyl); pmCylSphConvert(&cyl, &sph); toSph(sph, this); } double &PM_SPHERICAL::operator [] (int n) { switch (n) { case 0: return theta; case 1: return phi; case 2: return r; default: return noElement; // need to return a double & } } #ifdef INCLUDE_POSEMATH_COPY_CONSTRUCTORS PM_SPHERICAL::PM_SPHERICAL(PM_CCONST PM_SPHERICAL & s) { theta = s.theta; phi = s.phi; r = s.r; } #endif // PM_CYLINDRICAL PM_CYLINDRICAL::PM_CYLINDRICAL(double _theta, double _r, double _z) { theta = _theta; r = _r; z = _z; } PM_CYLINDRICAL::PM_CYLINDRICAL(PM_CONST PM_CARTESIAN PM_REF v) { PmCartesian cart; PmCylindrical cyl; toCart(v, &cart); pmCartCylConvert(&cart, &cyl); toCyl(cyl, this); } PM_CYLINDRICAL::PM_CYLINDRICAL(PM_CONST PM_SPHERICAL PM_REF s) { PmSpherical sph; PmCylindrical cyl; toSph(s, &sph); pmSphCylConvert(&sph, &cyl); toCyl(cyl, this); } double &PM_CYLINDRICAL::operator [] (int n) { switch (n) { case 0: return theta; case 1: return r; case 2: return z; default: return noElement; // need to return a double & } } #ifdef INCLUDE_POSEMATH_COPY_CONSTRUCTORS PM_CYLINDRICAL::PM_CYLINDRICAL(PM_CCONST PM_CYLINDRICAL & c) { theta = c.theta; r = c.r; z = c.z; } #endif // PM_ROTATION_VECTOR PM_ROTATION_VECTOR::PM_ROTATION_VECTOR(double _s, double _x, double _y, double _z) { PmRotationVector rv; rv.s = _s; rv.x = _x; rv.y = _y; rv.z = _z; pmRotNorm(&rv, &rv); toRot(rv, this); } PM_ROTATION_VECTOR::PM_ROTATION_VECTOR(PM_CONST PM_QUATERNION PM_REF q) { PmQuaternion quat; PmRotationVector rv; toQuat(q, &quat); pmQuatRotConvert(&quat, &rv); toRot(rv, this); } double &PM_ROTATION_VECTOR::operator [] (int n) { switch (n) { case 0: return s; case 1: return x; case 2: return y; case 3: return z; default: return noElement; // need to return a double & } } #ifdef INCLUDE_POSEMATH_COPY_CONSTRUCTORS PM_ROTATION_VECTOR::PM_ROTATION_VECTOR(PM_CCONST PM_ROTATION_VECTOR & r) { s = r.s; x = r.x; y = r.y; z = r.z; } #endif // PM_ROTATION_MATRIX class // ctors/dtors PM_ROTATION_MATRIX::PM_ROTATION_MATRIX(double xx, double xy, double xz, double yx, double yy, double yz, double zx, double zy, double zz) { x.x = xx; x.y = xy; x.z = xz; y.x = yx; y.y = yy; y.z = yz; z.x = zx; z.y = zy; z.z = zz; /*! \todo FIXME-- need a matrix orthonormalization function pmMatNorm() */ } PM_ROTATION_MATRIX::PM_ROTATION_MATRIX(PM_CARTESIAN _x, PM_CARTESIAN _y, PM_CARTESIAN _z) { x = _x; y = _y; z = _z; } PM_ROTATION_MATRIX::PM_ROTATION_MATRIX(PM_CONST PM_ROTATION_VECTOR PM_REF v) { PmRotationVector rv; PmRotationMatrix mat; toRot(v, &rv); pmRotMatConvert(&rv, &mat); toMat(mat, this); } PM_ROTATION_MATRIX::PM_ROTATION_MATRIX(PM_CONST PM_QUATERNION PM_REF q) { PmQuaternion quat; PmRotationMatrix mat; toQuat(q, &quat); pmQuatMatConvert(&quat, &mat); toMat(mat, this); } PM_ROTATION_MATRIX::PM_ROTATION_MATRIX(PM_CONST PM_RPY PM_REF rpy) { PmRpy _rpy; PmRotationMatrix mat; toRpy(rpy, &_rpy); pmRpyMatConvert(&_rpy, &mat); toMat(mat, this); } PM_ROTATION_MATRIX::PM_ROTATION_MATRIX(PM_CONST PM_EULER_ZYZ PM_REF zyz) { PmEulerZyz _zyz; PmRotationMatrix mat; toEulerZyz(zyz, &_zyz); pmZyzMatConvert(&_zyz, &mat); toMat(mat, this); } PM_ROTATION_MATRIX::PM_ROTATION_MATRIX(PM_CONST PM_EULER_ZYX PM_REF zyx) { PmEulerZyx _zyx; PmRotationMatrix mat; toEulerZyx(zyx, &_zyx); pmZyxMatConvert(&_zyx, &mat); toMat(mat, this); } // operators PM_CARTESIAN & PM_ROTATION_MATRIX::operator [](int n) { switch (n) { case 0: return x; case 1: return y; case 2: return z; default: if (0 == noCart) { noCart = new PM_CARTESIAN(0.0, 0.0, 0.0); } return (*noCart); // need to return a PM_CARTESIAN & } } #ifdef INCLUDE_POSEMATH_COPY_CONSTRUCTORS PM_ROTATION_MATRIX::PM_ROTATION_MATRIX(PM_CCONST PM_ROTATION_MATRIX & m) { x = m.x; y = m.y; z = m.z; } #endif // PM_QUATERNION class PM_QUATERNION::PM_QUATERNION(double _s, double _x, double _y, double _z) { PmQuaternion quat; quat.s = _s; quat.x = _x; quat.y = _y; quat.z = _z; pmQuatNorm(&quat, &quat); s = quat.s; x = quat.x; y = quat.y; z = quat.z; } PM_QUATERNION::PM_QUATERNION(PM_CONST PM_ROTATION_VECTOR PM_REF v) { PmRotationVector rv; PmQuaternion quat; toRot(v, &rv); pmRotQuatConvert(&rv, &quat); toQuat(quat, this); } PM_QUATERNION::PM_QUATERNION(PM_CONST PM_ROTATION_MATRIX PM_REF m) { PmRotationMatrix mat; PmQuaternion quat; toMat(m, &mat); pmMatQuatConvert(&mat, &quat); toQuat(quat, this); } PM_QUATERNION::PM_QUATERNION(PM_CONST PM_EULER_ZYZ PM_REF zyz) { PmEulerZyz _zyz; PmQuaternion quat; toEulerZyz(zyz, &_zyz); pmZyzQuatConvert(&_zyz, &quat); toQuat(quat, this); } PM_QUATERNION::PM_QUATERNION(PM_CONST PM_EULER_ZYX PM_REF zyx) { PmEulerZyx _zyx; PmQuaternion quat; toEulerZyx(zyx, &_zyx); pmZyxQuatConvert(&_zyx, &quat); toQuat(quat, this); } PM_QUATERNION::PM_QUATERNION(PM_CONST PM_RPY PM_REF rpy) { PmRpy _rpy; PmQuaternion quat; toRpy(rpy, &_rpy); pmRpyQuatConvert(&_rpy, &quat); toQuat(quat, this); } PM_QUATERNION::PM_QUATERNION(PM_AXIS _axis, double _angle) { PmQuaternion quat; pmAxisAngleQuatConvert((PmAxis) _axis, _angle, &quat); toQuat(quat, this); } void PM_QUATERNION::axisAngleMult(PM_AXIS _axis, double _angle) { PmQuaternion quat; toQuat((*this), &quat); pmQuatAxisAngleMult(&quat, (PmAxis) _axis, _angle, &quat); toQuat(quat, this); } double &PM_QUATERNION::operator [] (int n) { switch (n) { case 0: return s; case 1: return x; case 2: return y; case 3: return z; default: return noElement; // need to return a double & } } #ifdef INCLUDE_POSEMATH_COPY_CONSTRUCTORS PM_QUATERNION::PM_QUATERNION(PM_CCONST PM_QUATERNION & q) { s = q.s; x = q.x; y = q.y; z = q.z; } #endif // PM_EULER_ZYZ class PM_EULER_ZYZ::PM_EULER_ZYZ(double _z, double _y, double _zp) { z = _z; y = _y; zp = _zp; } PM_EULER_ZYZ::PM_EULER_ZYZ(PM_CONST PM_QUATERNION PM_REF q) { PmQuaternion quat; PmEulerZyz zyz; toQuat(q, &quat); pmQuatZyzConvert(&quat, &zyz); toEulerZyz(zyz, this); } PM_EULER_ZYZ::PM_EULER_ZYZ(PM_CONST PM_ROTATION_MATRIX PM_REF m) { PmRotationMatrix mat; PmEulerZyz zyz; toMat(m, &mat); pmMatZyzConvert(&mat, &zyz); toEulerZyz(zyz, this); } double &PM_EULER_ZYZ::operator [] (int n) { switch (n) { case 0: return z; case 1: return y; case 2: return zp; default: return noElement; // need to return a double & } } #ifdef INCLUDE_POSEMATH_COPY_CONSTRUCTORS PM_EULER_ZYZ::PM_EULER_ZYZ(PM_CCONST PM_EULER_ZYZ & zyz) { z = zyz.z; y = zyz.y; zp = zyz.zp; } #endif // PM_EULER_ZYX class PM_EULER_ZYX::PM_EULER_ZYX(double _z, double _y, double _x) { z = _z; y = _y; x = _x; } PM_EULER_ZYX::PM_EULER_ZYX(PM_CONST PM_QUATERNION PM_REF q) { PmQuaternion quat; PmEulerZyx zyx; toQuat(q, &quat); pmQuatZyxConvert(&quat, &zyx); toEulerZyx(zyx, this); } PM_EULER_ZYX::PM_EULER_ZYX(PM_CONST PM_ROTATION_MATRIX PM_REF m) { PmRotationMatrix mat; PmEulerZyx zyx; toMat(m, &mat); pmMatZyxConvert(&mat, &zyx); toEulerZyx(zyx, this); } double &PM_EULER_ZYX::operator [] (int n) { switch (n) { case 0: return z; case 1: return y; case 2: return x; default: return noElement; // need to return a double & } } #ifdef INCLUDE_POSEMATH_COPY_CONSTRUCTORS PM_EULER_ZYX::PM_EULER_ZYX(PM_CCONST PM_EULER_ZYX & zyx) { z = zyx.z; y = zyx.y; x = zyx.x; } #endif // PM_RPY class #ifdef INCLUDE_POSEMATH_COPY_CONSTRUCTORS PM_RPY::PM_RPY(PM_CCONST PM_RPY & rpy) { r = rpy.r; p = rpy.p; y = rpy.y; } #endif PM_RPY::PM_RPY(double _r, double _p, double _y) { r = _r; p = _p; y = _y; } PM_RPY::PM_RPY(PM_CONST PM_QUATERNION PM_REF q) { PmQuaternion quat; PmRpy rpy; toQuat(q, &quat); pmQuatRpyConvert(&quat, &rpy); toRpy(rpy, this); } PM_RPY::PM_RPY(PM_CONST PM_ROTATION_MATRIX PM_REF m) { PmRotationMatrix mat; PmRpy rpy; toMat(m, &mat); pmMatRpyConvert(&mat, &rpy); toRpy(rpy, this); } double &PM_RPY::operator [] (int n) { switch (n) { case 0: return r; case 1: return p; case 2: return y; default: return noElement; // need to return a double & } } // PM_POSE class PM_POSE::PM_POSE(PM_CARTESIAN v, PM_QUATERNION q) { tran.x = v.x; tran.y = v.y; tran.z = v.z; rot.s = q.s; rot.x = q.x; rot.y = q.y; rot.z = q.z; } PM_POSE::PM_POSE(double x, double y, double z, double s, double sx, double sy, double sz) { tran.x = x; tran.y = y; tran.z = z; rot.s = s; rot.x = sx; rot.y = sy; rot.z = sz; } PM_POSE::PM_POSE(PM_CONST PM_HOMOGENEOUS PM_REF h) { PmHomogeneous hom; PmPose pose; toHom(h, &hom); pmHomPoseConvert(&hom, &pose); toPose(pose, this); } double &PM_POSE::operator [] (int n) { switch (n) { case 0: return tran.x; case 1: return tran.y; case 2: return tran.z; case 3: return rot.s; case 4: return rot.x; case 5: return rot.y; case 6: return rot.z; default: return noElement; // need to return a double & } } #ifdef INCLUDE_POSEMATH_COPY_CONSTRUCTORS PM_POSE::PM_POSE(PM_CCONST PM_POSE & p) { tran = p.tran; rot = p.rot; } #endif // PM_HOMOGENEOUS class PM_HOMOGENEOUS::PM_HOMOGENEOUS(PM_CARTESIAN v, PM_ROTATION_MATRIX m) { tran = v; rot = m; } PM_HOMOGENEOUS::PM_HOMOGENEOUS(PM_CONST PM_POSE PM_REF p) { PmPose pose; PmHomogeneous hom; toPose(p, &pose); pmPoseHomConvert(&pose, &hom); toHom(hom, this); } PM_CARTESIAN & PM_HOMOGENEOUS::operator [](int n) { // if it is a rotation vector, stuff 0 as default bottom // if it is a translation vector, stuff 1 as default bottom switch (n) { case 0: noElement = 0.0; return rot.x; case 1: noElement = 0.0; return rot.y; case 2: noElement = 0.0; return rot.z; case 3: noElement = 1.0; return tran; default: if (0 == noCart) { noCart = new PM_CARTESIAN(0.0, 0.0, 0.0); } return (*noCart); // need to return a PM_CARTESIAN & } } #ifdef INCLUDE_POSEMATH_COPY_CONSTRUCTORS PM_HOMOGENEOUS::PM_HOMOGENEOUS(PM_CCONST PM_HOMOGENEOUS & h) { tran = h.tran; rot = h.rot; } #endif // PM_LINE class #ifdef INCLUDE_POSEMATH_COPY_CONSTRUCTORS PM_LINE::PM_LINE(PM_CCONST PM_LINE & l) { start = l.start; end = l.end; uVec = l.uVec; } #endif int PM_LINE::init(PM_POSE start, PM_POSE end) { PmLine _line; PmPose _start, _end; int retval; toPose(start, &_start); toPose(end, &_end); retval = pmLineInit(&_line, &_start, &_end); toLine(_line, this); return retval; } int PM_LINE::point(double len, PM_POSE * point) { PmLine _line; PmPose _point; int retval; toLine(*this, &_line); retval = pmLinePoint(&_line, len, &_point); toPose(_point, point); return retval; } // PM_CIRCLE class #ifdef INCLUDE_POSEMATH_COPY_CONSTRUCTORS PM_CIRCLE::PM_CIRCLE(PM_CCONST PM_CIRCLE & c) { center = c.center; normal = c.normal; rTan = c.rTan; rPerp = c.rPerp; rHelix = c.rHelix; radius = c.radius; angle = c.angle; spiral = c.spiral; } #endif int PM_CIRCLE::init(PM_POSE start, PM_POSE end, PM_CARTESIAN center, PM_CARTESIAN normal, int turn) { PmCircle _circle; PmPose _start, _end; PmCartesian _center, _normal; int retval; toPose(start, &_start); toPose(end, &_end); toCart(center, &_center); toCart(normal, &_normal); retval = pmCircleInit(&_circle, &_start.tran, &_end.tran, &_center, &_normal, turn); toCircle(_circle, this); return retval; } int PM_CIRCLE::point(double angle, PM_POSE * point) { PmCircle _circle; PmPose _point; int retval; toCircle(*this, &_circle); retval = pmCirclePoint(&_circle, angle, &_point.tran); toPose(_point, point); return retval; } // overloaded external functions // dot double dot(const PM_CARTESIAN &v1, const PM_CARTESIAN &v2) { double d; PmCartesian _v1, _v2; toCart(v1, &_v1); toCart(v2, &_v2); pmCartCartDot(&_v1, &_v2, &d); return d; } // cross PM_CARTESIAN cross(const PM_CARTESIAN &v1, const PM_CARTESIAN &v2) { PM_CARTESIAN ret; PmCartesian _v1, _v2; toCart(v1, &_v1); toCart(v2, &_v2); pmCartCartCross(&_v1, &_v2, &_v1); toCart(_v1, &ret); return ret; } //unit PM_CARTESIAN unit(const PM_CARTESIAN &v) { PM_CARTESIAN vout; PmCartesian _v; toCart(v, &_v); pmCartUnitEq(&_v); toCart(_v, &vout); return vout; } /*! \todo Another #if 0 */ #if 0 PM_CARTESIAN norm(PM_CARTESIAN v) { PM_CARTESIAN vout; PmCartesian _v; toCart(v, &_v); pmCartNorm(&_v, &_v); toCart(_v, &vout); return vout; } PM_QUATERNION norm(PM_QUATERNION q) { PM_QUATERNION qout; PmQuaternion _q; toQuat(q, &_q); pmQuatNorm(_q, &_q); toQuat(_q, &qout); return qout; } PM_ROTATION_VECTOR norm(PM_ROTATION_VECTOR r) { PM_ROTATION_VECTOR rout; PmRotationVector _r; toRot(r, &_r); pmRotNorm(_r, &_r); toRot(_r, &rout); return rout; } PM_ROTATION_MATRIX norm(PM_ROTATION_MATRIX m) { PM_ROTATION_MATRIX mout; PmRotationMatrix _m; toMat(m, &_m); pmMatNorm(_m, &_m); toMat(_m, &mout); return mout; } #endif // isNorm int isNorm(PM_CARTESIAN v) { PmCartesian _v; toCart(v, &_v); return pmCartIsNorm(&_v); } int isNorm(PM_QUATERNION q) { PmQuaternion _q; toQuat(q, &_q); return pmQuatIsNorm(&_q); } int isNorm(PM_ROTATION_VECTOR r) { PmRotationVector _r; toRot(r, &_r); return pmRotIsNorm(&_r); } int isNorm(PM_ROTATION_MATRIX m) { PmRotationMatrix _m; toMat(m, &_m); return pmMatIsNorm(&_m); } // mag double mag(const PM_CARTESIAN &v) { double ret; PmCartesian _v; toCart(v, &_v); pmCartMag(&_v, &ret); return ret; } // disp double disp(const PM_CARTESIAN &v1, const PM_CARTESIAN &v2) { double ret; PmCartesian _v1, _v2; toCart(v1, &_v1); toCart(v2, &_v2); pmCartCartDisp(&_v1, &_v2, &ret); return ret; } // inv PM_CARTESIAN inv(const PM_CARTESIAN &v) { PM_CARTESIAN ret; PmCartesian _v; toCart(v, &_v); pmCartInv(&_v, &_v); toCart(_v, &ret); return ret; } PM_ROTATION_MATRIX inv(const PM_ROTATION_MATRIX &m) { PM_ROTATION_MATRIX ret; PmRotationMatrix _m; toMat(m, &_m); pmMatInv(&_m, &_m); toMat(_m, &ret); return ret; } PM_QUATERNION inv(const PM_QUATERNION &q) { PM_QUATERNION ret; PmQuaternion _q; toQuat(q, &_q); pmQuatInv(&_q, &_q); toQuat(_q, &ret); return ret; } PM_POSE inv(const PM_POSE &p) { PM_POSE ret; PmPose _p; toPose(p, &_p); pmPoseInv(&_p, &_p); toPose(_p, &ret); return ret; } PM_HOMOGENEOUS inv(const PM_HOMOGENEOUS &h) { PM_HOMOGENEOUS ret; PmHomogeneous _h; toHom(h, &_h); pmHomInv(&_h, &_h); toHom(_h, &ret); return ret; } // project PM_CARTESIAN proj(const PM_CARTESIAN &v1, PM_CARTESIAN &v2) { PM_CARTESIAN ret; PmCartesian _v1, _v2; toCart(v1, &_v1); toCart(v2, &_v2); pmCartCartProj(&_v1, &_v2, &_v1); toCart(_v1, &ret); return ret; } // overloaded arithmetic operators PM_CARTESIAN operator +(const PM_CARTESIAN &v) { return v; } PM_CARTESIAN operator -(const PM_CARTESIAN &v) { PM_CARTESIAN ret; ret.x = -v.x; ret.y = -v.y; ret.z = -v.z; return ret; } PM_QUATERNION operator +(const PM_QUATERNION &q) { return q; } PM_QUATERNION operator -(const PM_QUATERNION &q) { PM_QUATERNION ret; PmQuaternion _q; toQuat(q, &_q); pmQuatInv(&_q, &_q); toQuat(_q, &ret); return ret; } PM_POSE operator +(const PM_POSE &p) { return p; } PM_POSE operator -(const PM_POSE &p) { PM_POSE ret; PmPose _p; toPose(p, &_p); pmPoseInv(&_p, &_p); toPose(_p, &ret); return ret; } int operator ==(const PM_CARTESIAN &v1, const PM_CARTESIAN &v2) { PmCartesian _v1, _v2; toCart(v1, &_v1); toCart(v2, &_v2); return pmCartCartCompare(&_v1, &_v2); } int operator ==(const PM_QUATERNION &q1, PM_QUATERNION &q2) { PmQuaternion _q1, _q2; toQuat(q1, &_q1); toQuat(q2, &_q2); return pmQuatQuatCompare(&_q1, &_q2); } int operator ==(const PM_POSE &p1, const PM_POSE &p2) { PmPose _p1, _p2; toPose(p1, &_p1); toPose(p2, &_p2); return pmPosePoseCompare(&_p1, &_p2); } int operator !=(const PM_CARTESIAN &v1, const PM_CARTESIAN &v2) { PmCartesian _v1, _v2; toCart(v1, &_v1); toCart(v2, &_v2); return !pmCartCartCompare(&_v1, &_v2); } int operator !=(const PM_QUATERNION &q1, const PM_QUATERNION &q2) { PmQuaternion _q1, _q2; toQuat(q1, &_q1); toQuat(q2, &_q2); return !pmQuatQuatCompare(&_q1, &_q2); } int operator !=(const PM_POSE &p1, const PM_POSE &p2) { PmPose _p1, _p2; toPose(p1, &_p1); toPose(p2, &_p2); return !pmPosePoseCompare(&_p1, &_p2); } PM_CARTESIAN operator +(PM_CARTESIAN v1, const PM_CARTESIAN &v2) { v1 += v2; return v1; } PM_CARTESIAN operator -(PM_CARTESIAN v1, const PM_CARTESIAN &v2) { v1 -= v2; return v1; } PM_CARTESIAN operator *(PM_CARTESIAN v, double s) { v *= s; return v; } PM_CARTESIAN operator *(double s, PM_CARTESIAN v) { v *= s; return v; } PM_CARTESIAN operator /(const PM_CARTESIAN &v, double s) { PM_CARTESIAN ret; #ifdef PM_DEBUG if (s == 0.0) { #ifdef PM_PRINT_ERROR pmPrintError("PM_CARTESIAN::operator / : divide by 0\n"); #endif pmErrno = PM_DIV_ERR; return ret; } #endif ret.x = v.x / s; ret.y = v.y / s; ret.z = v.z / s; return ret; } PM_QUATERNION operator *(double s, const PM_QUATERNION &q) { PM_QUATERNION qout; PmQuaternion _q; toQuat(q, &_q); pmQuatScalMult(&_q, s, &_q); toQuat(_q, &qout); return qout; } PM_QUATERNION operator *(const PM_QUATERNION &q, double s) { PM_QUATERNION qout; PmQuaternion _q; toQuat(q, &_q); pmQuatScalMult(&_q, s, &_q); toQuat(_q, &qout); return qout; } PM_QUATERNION operator /(const PM_QUATERNION &q, double s) { PM_QUATERNION qout; PmQuaternion _q; toQuat(q, &_q); #ifdef PM_DEBUG if (s == 0.0) { #ifdef PM_PRINT_ERROR pmPrintError("Divide by 0 in operator /\n"); #endif pmErrno = PM_NORM_ERR; /*! \todo Another #if 0 */ #if 0 // g++/gcc versions 2.8.x and 2.9.x // will complain that the call to PM_QUATERNION(PM_QUATERNION) is // ambigous. (2.7.x and some others allow it) return qout = PM_QUATERNION((double) 0, (double) 0, (double) 0, (double) 0); #else PmQuaternion quat; quat.s = 0; quat.x = 0; quat.y = 0; quat.z = 0; pmQuatNorm(&quat, &quat); qout.s = quat.s; qout.x = quat.x; qout.y = quat.y; qout.z = quat.z; return qout; #endif } #endif pmQuatScalMult(&_q, 1.0 / s, &_q); toQuat(_q, &qout); pmErrno = 0; return qout; } PM_CARTESIAN operator *(const PM_QUATERNION &q, const PM_CARTESIAN &v) { PM_CARTESIAN vout; PmQuaternion _q; PmCartesian _v; toQuat(q, &_q); toCart(v, &_v); pmQuatCartMult(&_q, &_v, &_v); toCart(_v, &vout); return vout; } PM_QUATERNION operator *(const PM_QUATERNION &q1, const PM_QUATERNION &q2) { PM_QUATERNION ret; PmQuaternion _q1, _q2; toQuat(q1, &_q1); toQuat(q2, &_q2); pmQuatQuatMult(&_q1, &_q2, &_q1); toQuat(_q1, &ret); return ret; } PM_ROTATION_MATRIX operator *(const PM_ROTATION_MATRIX &m1, const PM_ROTATION_MATRIX &m2) { PM_ROTATION_MATRIX ret; PmRotationMatrix _m1, _m2; toMat(m1, &_m1); toMat(m2, &_m2); pmMatMatMult(&_m1, &_m2, &_m1); toMat(_m1, &ret); return ret; } PM_POSE operator *(const PM_POSE &p1, const PM_POSE &p2) { PM_POSE ret; PmPose _p1, _p2; toPose(p1, &_p1); toPose(p2, &_p2); pmPosePoseMult(&_p1, &_p2, &_p1); toPose(_p1, &ret); return ret; } PM_CARTESIAN operator *(const PM_POSE &p, const PM_CARTESIAN &v) { PM_CARTESIAN ret; PmPose _p; PmCartesian _v; toPose(p, &_p); toCart(v, &_v); pmPoseCartMult(&_p, &_v, &_v); toCart(_v, &ret); return ret; }