四元数与旋转关系

    技术2022-05-19  20

    1、围绕一个轴旋转的Quaternion如何从几何意义上去思考 围绕轴旋转函数:FromAngleAxis( rfAngle, rkAxis );   Quaternion::IDENTITY 缺省状态下的XYZ轴信息 (X-红色,Y-绿色,Z-蓝色)     Ogre::Quaternion quat; quat.FromAngleAxis(Ogre::Radian(Ogre::Math::PI/2.0f), Ogre::Vector3(1,1,1) ); 围绕轴(1,1,1)旋转90度后的情况为:   从两个图中的信息来看,每次旋转其实都是指相对于缺省的Quaternion::IDENTITY 进行的。   引申一下,对于 Ogre::Vector3中的 getRotationTo(const Vector3& dest, const Vector3& fallbackAxis = Vector3::ZERO)  其会将从自身到dest的叉乘的向量为轴,dest到this之间的构成的角度为弧度旋转     2、四元数相乘顺序的问题,虽然有时候对四元数相乘顺序有一定了解。但是要熟练理解和掌握还有一些疑问。 我们先从一个例子来分析:   ///从欧拉角计算出旋转量  GetQuaterionFromEuler( double yawRadian,  double pitchRadian,  double rollRadian)  {       //绕Y轴旋转量      Ogre::Quaternion yawYAxis;      yawYAxis.FromAngleAxis(Ogre::Radian(yawRadian), Ogre::Vector3::UNIT_Y);         //绕X轴旋转量      Ogre::Quaternion pitchXAxis;      pitchXAxis.FromAngleAxis(Ogre::Radian(pitchRadian), Ogre::Vector3::UNIT_X);         //绕Z轴旋转量      Ogre::Quaternion rollZAxis;      rollZAxis.FromAngleAxis(Ogre::Radian(rollRadian), Ogre::Vector3::UNIT_Z);        Ogre::Quaternion quat = yawYAxis * (pitchXAxis * rollZAxis);  }      上面的这个变换过程的顺序是,首先绕Y轴做方位旋转Yaw,然后绕X轴做俯仰旋转Pitch,最后绕X轴做翻滚旋转Roll。 但是在实现的时候,四元数的操作顺序是 : yawYAxis*(pitchXAxis*rollZAxis); 通过这个顺序,不从机理上进行分析的话,那么就是后进行的变换操作,需要右乘前面的四元数。 我们再简单的分析一下,如果旋转变换quad1,与旋转变换quad2;如果quad2是在相对于quad1的空间内,做的旋转变换,那么最终的旋转变换应该是 quad1*quad2;   下面有段OgreNode.cpp中一段代码,从这段代码我们也可以了解四元数的旋转顺序关系。 enum TransformSpace  {       /// Transform is relative to the local space      TS_LOCAL,       /// Transform is relative to the space of the parent node      TS_PARENT,       /// Transform is relative to world space      TS_WORLD  };    void Node::rotate( const Quaternion &q, TransformSpace relativeTo)  {       // Normalise quaternion to avoid drift      Quaternion qnorm = q;      qnorm.normalise();       switch(relativeTo)      {         case TS_PARENT:           // Rotations are normally relative to local axes, transform up          mOrientation = qnorm * mOrientation;           break;       case TS_WORLD:           // Rotations are normally relative to local axes, transform up          mOrientation = mOrientation * _getDerivedOrientation().Inverse()                         * qnorm * _getDerivedOrientation();           break;       case TS_LOCAL:           // Note the order of the mult, i.e. q comes after          mOrientation = mOrientation * qnorm;           break;      }      needUpdate();  }       


    最新回复(0)