-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDualQuaternion.h
108 lines (87 loc) · 4.48 KB
/
DualQuaternion.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/***************************************************************************
* Copyright (c) 2019 Viktor Titov (DeepSOIC) <vv.titov@gmail.com> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef FREECAD_BASE_DUAL_QUATERNION_H
#define FREECAD_BASE_DUAL_QUATERNION_H
#include "DualNumber.h"
//#include <Console.h> //DEBUG
namespace Base {
/**
* @brief The DualQuat class represents a dual quaternion, as a quaternion of
* dual number components. Dual quaternions are useful for placement
* interpolation, see pow method.
*
* Rotation is stored as non-dual part of DualQ. Translation is encoded into
* dual part of DualQuat:
* DualQuat.dual() = 0.5 * t * r,
* where t is quaternion with x,y,z of translation and w of 0, and r is the
* rotation quaternion.
*/
class BaseExport DualQuat {
public:
DualNumber x;
DualNumber y;
DualNumber z;
DualNumber w;
public:
///default constructor: init with zeros
DualQuat(){}
DualQuat(DualNumber x, DualNumber y, DualNumber z, DualNumber w)
: x(x), y(y), z(z), w(w) {}
DualQuat(double x,double y,double z,double w,double dx,double dy,double dz,double dw)
: x(x, dx), y(y, dy), z(z, dz), w(w, dw) {}
DualQuat(double x,double y,double z,double w)
: x(x), y(y), z(z), w(w) {}
///Builds a dual quaternion from real and dual parts provided as pure real quaternions
DualQuat(DualQuat re, DualQuat du);
///returns dual quaternion for identity placement
static DualQuat identity() {return DualQuat(0.0, 0.0, 0.0, 1.0);}
///return a copy with dual part zeroed out
DualQuat real() const {return DualQuat(x.re, y.re, z.re, w.re);}
///return a real-only quaternion made from dual part of this quaternion.
DualQuat dual() const {return DualQuat(x.du, y.du, z.du, w.du);}
///conjugate
DualQuat conj() const {return DualQuat(-x, -y, -z, w);}
///return vector part (with scalar part zeroed out)
DualQuat vec() const {return DualQuat(x,y,z,0.0);}
///magnitude of the quaternion
double length() const {return sqrt(x.re*x.re + y.re*y.re + z.re*z.re + w.re*w.re);}
///angle of rotation represented by this quaternion, in radians
double theta() const {return 2.0 * atan2(vec().length(), w.re);}
///dot product between real (rotation) parts of two dual quaternions (to determine if one of them should be negated for shortest interpolation)
static double dot(DualQuat a, DualQuat b);
///ScLERP. t=0.0 returns identity, t=1.0 returns this. t can also be outside of 0..1 bounds.
DualQuat pow(double t, bool shorten = true) const;
DualQuat operator-() const {return DualQuat(-x, -y, -z, -w);}
//DEBUG
//void print() const {
// Console().Log("%f, %f, %f, %f; %f, %f, %f, %f", x.re,y.re,z.re,w.re, x.du,y.du,z.du, w.du);
//}
};
DualQuat operator+(DualQuat a, DualQuat b);
DualQuat operator-(DualQuat a, DualQuat b);
DualQuat operator*(DualQuat a, DualQuat b);
DualQuat operator*(DualQuat a, double b);
DualQuat operator*(double a, DualQuat b);
DualQuat operator*(DualQuat a, DualNumber b);
DualQuat operator*(DualNumber a, DualQuat b);
} //namespace
#endif