zoukankan      html  css  js  c++  java
  • OSG:先导篇 数据类型:四元数

    一.简介

    欧拉角代表了三维向量中的偏转角度

    四元数代表了当有了欧拉角之后,还要根据哪个轴来旋转

    矩阵变换包含了平移变换 旋转变换  缩放变换

    三个可以互相转换

    二.osg::Quat类

    1.构造函数

    class OSG_EXPORT Quat
    {
    public:
      typedef double value_type;
    
      value_type _v[4];
    
      inline Quat() {_v[0] = 0.0; _v[1] = 0.0; _v[2] = 0.0;_v[3] = 1.0;}
      inline Quat(value_type x, value_type y, value_type z, value_type w)
      {
        _v[0] = x;
        _v[1] = y;
        _v[2] = z;
        _v[3] = w;
      }
      inline Quat(const Vec4f& v)
      {
        _v[0] = v.x();
        _v[1] = v.y();
        _v[2] = v.z();
        _v[3] = v.w();
      }
      inline Quat(const Vec4d& v)
      {
        _v[0] = v.x();
        _v[1] = v.y();
        _v[2] = v.z();
        _v[3] = v.w();
      }
      inline Quat(value_type angle, const Vec3f& axis)
      {
        makeRotate(angle, axis);
      }
      inline Quat(value_type angle, const Vec3d& axis)
      {
        makeRotate(angle, axis);
      }
      inline Quat(value_type angle1, const Vec3f& axis1,
                       value_type angle2, const Vec3f& axis2,
                       value_type angle3, const Vec3f& axis3)
      {
        makeRotate(angle1, axis1, angle2, axis2, angle3, axis3);
      }
      inline Quat(value_type angle1, const Vec3d& axis1,
                       value_type angle2, const Vec3d& axis2,
                       value_type angle3, const Vec3d& axis3)
      {
        makeRotate(angle1, axis1, angle2, axis2, angle3, axis3);
      }
    };

    2.重载操作符函数

    inline Quat& operator = (const Quat& v)
    {
      _v[0] = v._v[0];
      _v[1] = v._v[1];
      _v[2] = v._v[2];
      _v[3] = v._v[3];
      return *this;
    }
    
    inline bool operator == (const Quat& v) const 
    {
      return _v[0] == v._v[0] && _v[1] == v._v[1] && _v[2] == v._v[2] && _v[3] == v._v[3];
    }
    
    inline bool operator != (const Quat& v) const 
    {
      return _v[0] != v._v[0] || _v[1] != v._v[1] || _v[2] != v._v[2] || _v[3] != v._v[3];
    }
    
    inline bool operator < (const Quat& v) const 
    {
      if(_v[0] < v._v[0]) return true;
      else if(_v[0] > v._v[0])  return false;
      else if(_v[1] < v._v[1])  return true;
      else if(_v[1] > v._v[1])  return false;
      else if(_v[2] < v._v[2])  return true;
      else if(_v[2] > v._v[2])  return false;
      else return (_v[3] < v._v[3]);
    }
    
    inline value_type& operator [] (int i) { return _v[i]; }
    inline value_type operator [] (int i) const {return _v[i];}
    
    inline const Quat operator * (value_type rhs) const
    {
      return Quat(_v[0] * rhs, _v[1] * rhs, _v[2] * rhs, _v[3] * rhs);
    }
    
    inline Quat& operator *= (value_type rhs)
    {
      _v[0] *= rhs;
      _v[1] *= rhs;
      _v[2] *= rhs'
      _v[3] *= rhs;
      return *this;
    }
    
    inline const Quat operator * (const Quat& rhs) const
    {
      return Quat( rhs._v[3]*_v[0] + rhs._v[0]*_v[3] + rhs._v[1]*_v[2] - rhs._v[2]*_v[1],
                     rhs._v[3]*_v[1] - rhs._v[0]*_v[2] + rhs._v[1]*_v[3] + rhs._v[2]*_v[0],
                     rhs._v[3]*_v[2] + rhs._v[0]*_v[1] - rhs._v[1]*_v[0] + rhs._v[2]*_v[3],
                     rhs._v[3]*_v[3] - rhs._v[0]*_v[0] - rhs._v[1]*_v[1] - rhs._v[2]*_v[2] );
    }
    
    inline Quat& operator *= (const Quat* rhs)
    {
      value_type x = rhs._v[3] * _v[0] + rhs._v[0] * _v[3] + rhs._v[1] * _v[2] - rhs._v[2] * _v[1];
      value_type y = rhs._v[3] * _v[1] - rhs._v[0] * _v[2] + rhs._v[1] * _v[3] - rhs._v[2] * _v[0];
      value_type z = rhs._v[3] * _v[2] + rhs._v[0] * _v[1] - rhs._v[1] * _v[0] + rhs._v[2] * _v[3];
      _v[3] = rhs._v[3] * _v[3] - rhs._v[0] * _v[0] - rhs._v[1] * _v[1] - rhs._v[2] * _v[2];
    
      _v[2] = z;
      _v[1] = y;
      _v[0] = x;
    
      return (*this);
    }
    
    inline Quat operator / (value_type rhs) const
    {
      value_type div = 1.0 / rhs;
      return Quat(_v[0] * div, _v[1] * div, _v[2] * div, _v[3] * div);
    }
    
    inline Quat& operator /= (value_type rhs)
    {
      value_type div = 1.0 / rhs;
      _v[0] *= div;
      _v[1] *= div;
      _v[2] *= div;
      _v[3] *= div;
      return *this;
    }
    
    inline const Quat operator / (const Quat& denom) const
    {
      return ( (*this) * denom.inverse() );
    }
    
    inline Quat& operator /= (const Quat& denom)
    {
      (*this) = (*this) * denom.inverse();
      return (*this);
    }
    
    inline const Quat operator + (const Quat& rhs) const
    {
      return Quat(_v[0] +  rhs._v[0], _v[1] + rhs._v[1], _v[2] + rhs._v[2], _v[3] + rhs._v[3]);
    }
    
    inline Quat& operator += (const Quat& rhs)
    {
      _v[0] += rhs._v[0];
      _v[1] += rhs._v[1];
      _v[2] += rhs._v[2];
      _v[3] += rhs._v[3];
      return *this;
    }
    
    inline const Quat operator - (const Quat& rhs) const
    {
      return Quat(_v[0] - rhs._v[0], _v[1] - rhs._v[1], _v[2] - rhs._v[2], _v[3] - rhs._v[3]);
    }
    
    inline Quat& operator -= (const Quat& rhs)
    {
      _v[0] -= rhs._v[0];
      _v[1] -= rhs._v[1];
      _v[2] -= rhs._v[2];
      _v[3] -= rhs._v[3];
      return *this;
    }
    
    inline const Quat operator - () const
    {
      return Quat(-_v[0], -_v[1], -_v[2], -_v[3]);
    }
    
    Vec3f operator * (const Vec3f& v) const 
    {
      Vec3f uv, uuv;
      Vec3f qvec(_v[0], _v[1], _v[2]);
      uv = qvec ^ v;
      uuv = qvec ^ uv;
      uv *= (2.0f * _v[3]);
      uuv *= 2.0f;
      return v + uv + uuv;
    }
    
    Vec3d operator* (const Vec3d& v) const
    {
      Vec3d uv, uuv;
      Vec3d qvec(_v[0], _v[1], _v[2]);
      uv = qvec ^ v;
      uuv = qvec ^ uv;
      uv *= (2.0f * _v[3]);
      uuv *= 2.0f;
      return v + uv + uuv;
    }

    3.成员函数

    inline Vec4d asVec4() const
    {
      return Vec4d(_v[0], _v[1], _v[2], _v[3]);
    }
    
    inline Vec3d asVec3() const
    {
      return Vec3d(_v[0], _v[1], _v[2]);
    }
    
    inline void set(value_type x, value_type y, value_type z, value_type w)
    {
      _v[0] = x;
      _v[1] = y;
      _v[2] = z;
      _v[3] = w;
    }
    
    inline void set(const osg::Vec4f& v)
    {
      _v[0] = v.x();
      _v[1] = v.y();
      _v[2] = v.z();
      _v[3] = v.w();
    }
    
    inline void set(const osg::Vec4d& v)
    {
      _v[0] = v.x();
      _v[1] = v.y();
      _v[2] = v.z();
      _v[3] = v.w();
    }
    
    void set(const Matrixf& matrix);
    void set(const Matrixd& matrix);
    void get(Matrixf& matrix) const;
    void get(Matrixd& matrix) const;
    
    inline value_type& x() { return _v[0]; }
    inline value_type& y() { return _v[1]; }
    inline value_type& z() { return _v[2]; }
    inline value_type& w() { return _v[3]; }
    
    inline value_type x() const { return _v[0]; }
    inline value_type y() const { return _v[1]; }
    inline value_type z() const { return _v[2]; }
    inline value_type w() const { return _v[3]; }
    
    bool zeroRotation() const { return _v[0] == 0.0 && _v[1] == 0.0 && _v[2] == 0.0 && _v[3] == 1.0; }
    
    value_type length() const
    {
      return sqrt( _v[0] * _v[0] + _v[1] * _v[1] + _v[2] * _v[2] + _v[3] * _v[3] );
    }
    
    value_type lenth2() const
    {
      return _v[0] * _v[0] + _v[1] * _v[1] + _v[2] * _v[2] + _v[3] * _v[3];
    }
    
    inline Quat conj () const
    {
      return Quat(-_v[0], -_v[1], -_v[2], _v[3]);
    }
    
    inline const Quat inverse () const
    {
      return conj() / length2();
    }
    
    void makeRotate(value_type angle, value_type x, value_type y, value_type z);
    void makeRotate(value_type angle, const Vec3f& vec);
    void makeRotate(value_type angle, const Vec3d& vec);
    void makeRotate(value_type angle1, const Vec3f& axis1,
                             value_type angle2, const Vec3d& axis2,
                             value_type angle3, const Vec3f& axis3);
    void makeRotate(value_type angle1, const Vec3d& axis1,
                             value_type angle2, const Vec3d& axis2,
                             value_type angle3, const Vec3d& axis3);
    
    void makeRotate(const Vec3f& vec1, const Vec3f& vec2);
    void makeRotate(const Vec3d& vec1, const Vec3d& vec2);
    void makeRotate_original(const Vec3d& vec1, const Vec3d& vec2);
    void getRotate(value_type& angle, value_type& x, value_type& y, value_type& z) const;
    void getRotate(value_type& angle, Vec3f& vec) const;
    void getRotate(value_type& angle, Vec3d& vec) const;
    void slerp(value_type t, const Quat& from, const Quat& to);
  • 相关阅读:
    CMake基本语法
    Immutable使用与react+redux
    mysql 安装之docker
    elasticsearch 安装之docker 单机
    局域网共享时提示:你没有权限访问,请与网络管理员联系
    【python、Neo4j】 python3.6环境安装neo4j客户端
    【python】 Anaconda jupyter 服务正常,内核启动失败, ipython启动失败
    Neo4j 手动安装apoc插件
    Ubuntu16 安装配置Neo4j
    node工具之nodemon
  • 原文地址:https://www.cnblogs.com/k5bg/p/11690797.html
Copyright © 2011-2022 走看看