我需要一个给定偏航角,俯仰角和横滚角的函数,可以在“世界坐标”中产生“前”(或“望”),“右”和“上” vector 。

在我的特定世界空间中,从原点(0,0,0)开始,X是向左的正数,Z是远离观察者/原点的正数,Y是向上的正数。

例如,给定...( Angular )

  • yaw = 0,pitch = 0,roll = 0,
    预期的输出是:
  • front =(0.0,0.0,1.0)
  • 右=(-1.0,0.0,0.0)
  • up =(0.0,1.0,0.0)
  • yaw = 90,pitch = 0,roll = 0,
    预期的输出是:
  • front =(1.0,0.0,0.0)
  • right =(0,0,0.0,1.0)
  • up =(0.0,1.0,0.0)
  • yaw = 0,pitch = 90,roll = 0,
    预期的输出是:
  • front =(0.0,1.0,0.0)
  • 右=(-1.0,0.0,0.0)
  • up =(0.0,0.0,-1.0)
  • yaw = 0,pitch = 0,roll = 90,
    预期的输出是:
  • front =(0.0,0.0,1.0)
  • right =(0.0,1.0,0.0)
  • up =(1.0,0.0,0.0)

  • 我使用的语言是C++,如果最有意义,我将很乐意使用glm解决此问题。如果我能通过四元数到达那里,那我也很满意该解决方案,因为我找到了其他教程来描述如何从欧拉角获得四元数。

    最佳答案

    这是一个完整的工作示例。它不是非常类似于C++。您可能希望使用一个真实的矩阵类,但是出于演示目的应该没问题。您的问题尚不清楚的一件事是轮换顺序,但可以轻松更改。

    #include <iostream>
    #include <cmath>
    #include <cstdlib>
    
    typedef float Float;
    typedef Float Axis[3];
    typedef Axis Axes[3];
    
    static void copy(const Axes &from,Axes &to)
    {
      for (size_t i=0; i!=3; ++i) {
        for (size_t j=0; j!=3; ++j) {
          to[i][j] = from[i][j];
        }
      }
    }
    
    static void mul(Axes &mat,Axes &b)
    {
      Axes result;
      for (size_t i=0; i!=3; ++i) {
        for (size_t j=0; j!=3; ++j) {
          Float sum = 0;
          for (size_t k=0; k!=3; ++k) {
            sum += mat[i][k]*b[k][j];
          }
          result[i][j] = sum;
        }
      }
      copy(result,mat);
    }
    
    static void getAxes(Axes &result,Float yaw,Float pitch,Float roll)
    {
      Float x = -pitch;
      Float y = yaw;
      Float z = -roll;
      Axes matX = {
        {1,     0,     0 },
        {0, cos(x),sin(x)},
        {0,-sin(x),cos(x)}
      };
      Axes matY = {
        {cos(y),0,-sin(y)},
        {     0,1,      0},
        {sin(y),0, cos(y)}
      };
      Axes matZ = {
        { cos(z),sin(z),0},
        {-sin(z),cos(z),0},
        {      0,     0,1}
      };
      Axes axes = {
        {1,0,0},
        {0,1,0},
        {0,0,1}
      };
    
      mul(axes,matX);
      mul(axes,matY);
      mul(axes,matZ);
    
      copy(axes,result);
    }
    
    
    static void showAxis(const char *desc,const Axis &axis,Float sign)
    {
      std::cout << "  " << desc << " = (";
      for (size_t i=0; i!=3; ++i) {
        if (i!=0) {
          std::cout << ",";
        }
        std::cout << axis[i]*sign;
      }
      std::cout << ")\n";
    }
    
    static void showAxes(const char *desc,Axes &axes)
    {
      std::cout << desc << ":\n";
      showAxis("front",axes[2],1);
      showAxis("right",axes[0],-1);
      showAxis("up",axes[1],1);
    }
    
    int main(int,char**)
    {
      Axes axes;
      std::cout.setf(std::ios::fixed);
      std::cout.precision(1);
      getAxes(axes,0,0,0);
      showAxes("yaw=0, pitch=0, roll=0",axes);
      getAxes(axes,M_PI/2,0,0);
      showAxes("yaw=90, pitch=0, roll=0",axes);
      getAxes(axes,0,M_PI/2,0);
      showAxes("yaw=0, pitch=90, roll=0",axes);
      getAxes(axes,0,0,M_PI/2);
      showAxes("yaw=0, pitch=0, roll=90",axes);
      return 0;
    }
    

    08-04 03:43