2013-04-18 47 views
3

我需要一個給定Yaw,Pitch和Roll的函數,可以在「世界座標」中產生Front(或Looking At),Right和Up矢量。如何將Euler角度轉換爲Front,Right,Right矢量

在我的特定世界空間中,從原點(0,0,0)開始,X向左爲正,Z爲正向遠離觀看者/原點,Y爲正向上。

對於例如,給定...(以度爲單位的角度)

  • 偏航= 0,音調= 0,滾= 0, 預期輸出是:

    • 前面= (0.0,0.0,1.0)
    • 右=(-1.0,0.0,0.0)
    • UP =(0.0,1.0,0.0)
  • 偏航= 90,變槳= 0,滾= 0, 預期輸出是:

    • 前面=(1.0,0.0,0.0)
    • 右=(0,0,0.0,1.0)
    • UP =(0.0,1.0,0.0)
  • 偏航= 0,節距= 90,輥= 0, 預期輸出是:

    • 前面=(0.0,1.0,0.0)
    • 右=(-1.0,0.0,0.0)
    • UP =(0.0,0.0,-1.0)
  • 偏航= 0,音調= 0,輥= 90, 預期輸出是:

    • 前面=(0.0,0.0,1.0)
    • 右=(0.0,1.0,0.0)
    • UP =(1.0,0.0,0.0 )

我的工作語言是C++的,我會很樂意使用GLM如果這是很有道理的,以解決這個問題。如果我可以通過quaternion來到那裏,那麼我也可以使用該解決方案,因爲我找到了其他教程來描述如何從歐拉角度獲得四元數。

+0

什麼是沒有旋轉的向量? – 2013-04-18 04:20:48

+0

我想你是問,如果我給它一個偏航= 0,音高= 0,滾動= 0,預期的結果是什麼。 在這種情況下的預期結果是: front =(0.0,0.0,1。0) right =( - 1.0,0.0,0.0) up =(0.0,1.0,0.0) 謝謝。 – 2013-04-18 04:43:12

+0

這與偏航結果相同= 90 – 2013-04-18 04:44:50

回答

2

這是一個完整的工作示例。這不是非常類似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; 
} 
+0

這是偉大的沃恩。我很欣賞代碼清楚地說明了如何進行矩陣乘法以及如何填充矩陣。 – 2013-04-18 17:03:48

+0

我認識到的一個小故障是我的規範中的一個問題。 我從我的研究中瞭解到,偏航,俯仰和滾轉的應用順序很重要。我想首先應用偏航,然後俯仰,然後滾動。我發現如果我改變矩陣的順序乘以: mul(axes,matZ); mul(axes,matX); mul(axes,matY); 我得到了我期待的行爲。 因此,我是否正確理解,我想按照如何使用修補程序玩具模型手動進行旋轉的相反順序進行這些乘法運算? 謝謝! – 2013-04-18 17:04:52

+0

@ BradHefta-Gaub:取決於你如何在模型上進行旋轉。代碼是用固定軸寫成的,而不是旋轉軸,但唯一的區別是乘法的順序。 – 2013-04-19 04:00:01