26 #include "DualQuaternion.hh"
27 #include <Base/Math/Matrix4x4.hh>
33 template <
class QUAT_TYPE>
42 dual.
Mult(real.Inverse(), qt);
43 translation.
Set(QUAT_TYPE(2.0)*qt[0], QUAT_TYPE(2.0)*qt[1], QUAT_TYPE(2.0)*qt[2]);
47 template <
class QUAT_TYPE>
56 dual[0] = d[0]; dual[1] = d[1]; dual[2] = d[2];
63 template <
class QUAT_TYPE>
70 GetRigidMotion(rotation, translation);
72 (PP_TYPE)translation[1],
73 (PP_TYPE)translation[2]),
77 (PP_TYPE)rotation[3]));
82 template <
class QUAT_TYPE>
89 (QUAT_TYPE)rotation[1],
90 (QUAT_TYPE)rotation[2],
91 (QUAT_TYPE)rotation[3]),
93 (QUAT_TYPE)translation[1],
94 (QUAT_TYPE)translation[2]));
98 template<
class QUAT_TYPE>
104 for (
register int i = 0; i < 4; i++) {
105 for (
register int j = 0; j < 4; j++) {
106 res[i][j] = res[i+4][j+4] = Lq[i][j];
107 res[i+4][j] = Lp[i][j];
114 template<
class QUAT_TYPE>
120 for (
register int i = 0; i < 4; i++) {
121 for (
register int j = 0; j < 4; j++) {
122 res[i][j] = res[i+4][j+4] = Rq[i][j];
123 res[i+4][j] = Rp[i][j];
130 template<
class QUAT_TYPE>
133 const QUAT_TYPE &t)
const
135 BIASASSERT(t >= QUAT_TYPE(0.0) && t <= QUAT_TYPE(1.0));
151 template<
class QUAT_TYPE>
154 const QUAT_TYPE &t)
const
156 BIASASSERT(t >= QUAT_TYPE(0.0) && t <= QUAT_TYPE(1.0));
171 template<
class QUAT_TYPE>
void
174 bool useOtherAngle,
bool useOtherPitch)
189 q0[3] = q1[3] = QUAT_TYPE(0.5) * (q0[3] + q1[3]);
193 p0[3] = p1[3] = QUAT_TYPE(0.5) * (p0[3] + p1[3]);
196 QUAT_TYPE q0norm = q0[0]*q0[0] + q0[1]*q0[1] + q0[2]*q0[2];
197 QUAT_TYPE q1norm = q1[0]*q1[0] + q1[1]*q1[1] + q1[2]*q1[2];
198 if (q0norm > QUAT_TYPE(1e-8) && q1norm > QUAT_TYPE(1e-8)) {
199 QUAT_TYPE qscale0 = (QUAT_TYPE)sqrt(
double((1-q0[3]*q0[3])/q0norm));
200 QUAT_TYPE qscale1 = (QUAT_TYPE)sqrt(
double((1-q1[3]*q1[3])/q1norm));
201 for (
register int l = 0; l < 3; l++) {
207 QUAT_TYPE q0p0 = q0[0]*p0[0]+q0[1]*p0[1]+q0[2]*p0[2];
208 QUAT_TYPE q1p1 = q1[0]*p1[0]+q1[1]*p1[1]+q1[2]*p1[2];
209 if ((q0p0 > 0 ? q0p0 > QUAT_TYPE(1e-8) : q0p0 < -QUAT_TYPE(1e-8)) &&
210 (q1p1 > 0 ? q1p1 > QUAT_TYPE(1e-8) : q1p1 < -QUAT_TYPE(1e-8))) {
211 QUAT_TYPE pscale0 = -q0[3]*p0[3]/q0p0;
212 QUAT_TYPE pscale1 = -q1[3]*p1[3]/q1p1;
213 for (
register int l = 0; l < 3; l++) {
223 template<
class QUAT_TYPE>
void
226 bool useFirstAngle,
bool useFirstPitch)
229 if (quats.empty())
return;
232 const int n = quats.size();
233 for (
int i = 0; i < n; i++)
234 quats[i].MakeUnique();
237 QUAT_TYPE a = quats[0].real[3], p = quats[0].dual[3];
238 if (!useFirstAngle) {
239 for (
int i = 1; i < n; i++)
240 a += quats[i].real[3];
243 if (!useFirstPitch) {
244 for (
int i = 1; i < n; i++)
245 p += quats[i].dual[3];
248 for (
int i = 0; i < n; i++) {
249 quats[i].real[3] = a;
250 quats[i].dual[3] = p;
254 for (
int i = 0; i < n; i++) {
256 QUAT_TYPE qnorm = q[0]*q[0] + q[1]*q[1] + q[2]*q[2];
257 if (qnorm > QUAT_TYPE(1e-8)) {
258 QUAT_TYPE qscale = (QUAT_TYPE)sqrt(
double((1-q[3]*q[3])/qnorm));
259 for (
register int l = 0; l < 3; l++)
265 for (
int i = 0; i < n; i++) {
268 QUAT_TYPE qp = q[0]*p[0]+q[1]*p[1]+q[2]*p[2];
269 if (qp > 0 ? (qp > QUAT_TYPE(1e-8)) : (qp < -QUAT_TYPE(1e-8))) {
270 QUAT_TYPE pscale = -q[3]*p[3]/qp;
271 for (
register int l = 0; l < 3; l++)
void Normalize()
Scales dual quaternion to unit length, i.e.
void Set(const T *pv)
copy the array of vectorsize beginning at *T to this->data_
void SetFromPoseParametrization(const PoseParametrization ¶ms)
void ScalarProduct(const Vector3< T > &argvec, T &result) const
scalar product (=inner product) of two vectors, storing the result in result
Quaternion< QUAT_TYPE > InterpolateLinear(const Quaternion< QUAT_TYPE > &to, const QUAT_TYPE &t) const
Linear interpolation between this and given quaternion.
PoseParametrization GetPoseParametrization() const
DualQuaternion< QUAT_TYPE > InterpolateLinear(const DualQuaternion< QUAT_TYPE > &to, const QUAT_TYPE &t) const
void EnforceRigidCouplingConstraint(DualQuaternion< QUAT_TYPE > &other, bool useOtherAngle=false, bool useOtherPitch=false)
Enforce rigid coupling constraint for this and the other given dual quaternion (equal rotation angle ...
class representing rigid motion by dual quaternions
Slim class bundeling pose parametrization and associated covariance matrix.
DualQuaternion< QUAT_TYPE > Interpolate(const DualQuaternion< QUAT_TYPE > &to, const QUAT_TYPE &t) const
void CrossProduct(const Vector3< T > &argvec, Vector3< T > &destvec) const
cross product of two vectors destvec = this x argvec
Matrix< QUAT_TYPE > GetLeftMultMatrix() const
Quaternion< QUAT_TYPE > Interpolate(const Quaternion< QUAT_TYPE > &to, const QUAT_TYPE &t) const
Spherical interpolation between this and given quaternion.
void GetRigidMotion(Quaternion< QUAT_TYPE > &rotation, Vector3< QUAT_TYPE > &translation) const
void Mult(const Quaternion< QUAT_TYPE > &quat)
quaternion multiplication: this= this * quat
class Vector3 contains a Vector of fixed dim.
Vector3< PP_TYPE > GetPosition() const
returns the position (first 3 entries) part of the pose parametrization vector
void Set(const Vector3< PP_TYPE > &position, const Quaternion< PP_TYPE > &orientation, const Matrix< PP_TYPE > &covariance=Matrix< double >(7, 7, MatrixZero))
Set this from position, orientation and covariance.
matrix class with arbitrary size, indexing is row major.
void MakeUnique()
Make dual quaternion representation unique with respect to the rigid motion it represents.
Matrix< QUAT_TYPE > GetRightMultMatrix() const
void SetFromRigidMotion(const Quaternion< QUAT_TYPE > &rotation, const Vector3< QUAT_TYPE > &translation)
is a 'fixed size' quadratic matrix of dim.
Quaternion< PP_TYPE > GetOrientation() const
returns the quaternion (last 4 entries) part of the pose parametrization vector