1 #ifndef VTESTBED_GEOMETRY_QUATERNION_HH     2 #define VTESTBED_GEOMETRY_QUATERNION_HH     6 #include <vtestbed/base/bstream.hh>     7 #include <vtestbed/geometry/math.hh>     8 #include <vtestbed/geometry/types.hh>    18             using vec4 = Vertex<T,4>;
    19             using vec3 = Vertex<T,3>;
    26             inline Quaternion(T s, T x, T y, T z): _data{s,x,y,z} {}
    27             inline Quaternion(
const vec4& q): _data{q(0),q(1),q(2),q(3)} {}
    28             inline Quaternion(T re, 
const vec3& im): _data{re,im(0),im(1),im(2)} {}
    29             inline T w()
 const { 
return this->_data[0]; }
    30             inline T x()
 const { 
return this->_data[1]; }
    31             inline T y()
 const { 
return this->_data[2]; }
    32             inline T z()
 const { 
return this->_data[3]; }
    34             inline T real()
 const { 
return w(); }
    35             inline vec3 imag()
 const { 
return {x(),y(),z()}; }
    36             inline T operator()(
int i)
 const { 
return this->_data[i]; }
    37             inline T operator[](
int i)
 const { 
return this->_data[i]; }
    38             inline const vec4& data()
 const { 
return this->_data; }
    60         template <
class T> 
inline T real(
const Quaternion<T>& q) { 
return q.real(); }
    61         template <
class T> 
inline Vertex<T,3> imag(
const Quaternion<T>& q) { 
return q.imag(); }
    66         operator*(
const Quaternion<T>& a, 
const Quaternion<T>& b);
    70         operator*=(Quaternion<T>& a, 
const Quaternion<T>& b) {
    77         operator*(
const Quaternion<T>& a, T b) {
    78             return {a(0)*b, a(1)*b, a(2)*b, a(3)*b};
    83         operator*(T a, 
const Quaternion<T>& b) {
    84             return {a*b(0), a*b(1), a*b(2), a*b(3)};
    89         operator/(
const Quaternion<T>& a, T b) {
    90             return {a(0)/b, a(1)/b, a(2)/b, a(3)/b};
    95         operator+(Quaternion<T>& a, 
const Quaternion<T>& b) {
    96             return Quaternion<T>{a(0)+b(0),a(1)+b(1),a(2)+b(2),a(3)+b(3)};
   101         operator+=(Quaternion<T>& a, 
const Quaternion<T>& b) {
   108         unit(
const Quaternion<T>& q) {
   109             return ::vtb::geometry::unit(q.data());
   114         length(
const Quaternion<T>& q) {
   131         from_euler_angles(
const Vertex<T,3>& angles);
   135         rotation_matrix(
const Quaternion<T>& q);
   139         from_vector(
const Quaternion<T>& q) {
   142             return Quaternion<T>{
   143                 sqrt(1 - pow2(q(1)) - pow2(q(2)) - pow2(q(3))),
   152         to_vector(
const Quaternion<T>& q) {
   153             return Quaternion<T>{0, q(1), q(2), q(3)};
   158         conj(
const Quaternion<T>& q) {
   159             return Quaternion<T>{q(0), -q(1), -q(2), -q(3)};
   164         rotate(
const Vertex<T,3>& v, 
const Quaternion<T>& q) {
   165             return (q*Quaternion<T>(T{},v)*conj(q)).imag();
   171             using scalar_type = T;
   172             using vertex_type = Vertex<T,3>;
   177             vertex_type _origin{T{}};
   186                                          const vertex_type& origin):
   187                 _quaternion(q), _quaternion_conj(q_conj), _origin(origin) {}
   193             inline const quaternion_type& quaternion()
 const { 
return this->_quaternion; }
   194             inline const quaternion_type& quaternion_conj()
 const { 
return this->_quaternion_conj; }
   198                 this->_quaternion = rhs, this->_quaternion_conj = conj(rhs);
   201             inline const vertex_type& origin()
 const { 
return this->_origin; }
   202             inline void origin(
const vertex_type& rhs) { this->_origin = rhs; }
   204             inline void clear() {
   205                 this->_quaternion.clear(), this->_quaternion_conj.clear(),
   213         make_coordinate_system(
const Quaternion<T>& q, 
const Vertex<T,3>& origin) {
   218         inline Quaternion_coordinate_system<T>
   219         make_coordinate_system(
const Quaternion<T>& q,
   220                                const Quaternion<T>& q_conj,
   221                                const Vertex<T,3>& origin) {
   222             return Quaternion_coordinate_system<T>(q, q_conj, origin);
   227         to(
const Quaternion_coordinate_system<T>& cs, 
const Vertex<T,3>& v) {
   228             Vertex<T,3> x = v-cs.origin();
   229             return rotate(x, cs.quaternion());
   234         from(
const Quaternion_coordinate_system<T>& cs, 
const Vertex<T,3>& v) {
   235             return rotate(v, cs.quaternion_conj()) + cs.origin();
   240         vector_to(
const Quaternion_coordinate_system<T>& cs, 
const Vertex<T,3>& v) {
   241             return rotate(v, cs.quaternion());
   246         vector_from(
const Quaternion_coordinate_system<T>& cs, 
const Vertex<T,3>& v) {
   247             return rotate(v, cs.quaternion_conj());
   254 #endif // vim:filetype=cpp 
T length(const blitz::TinyVector< T, N > &x)
Computes vector length without overflow.
 
Vertex< T, 3 > to_euler_angles(const Quaternion< T > &q)
Convert quaternion to Euler angles.