1. 程式人生 > >OSG 尤拉角 轉四元數 導航角(俯仰,偏航,橫滾)轉四元數 互轉

OSG 尤拉角 轉四元數 導航角(俯仰,偏航,橫滾)轉四元數 互轉

osg:: Quat的心得:
     先介紹四元數:Q = [w,(x,y,z)]被定義為一個四元數,w為一個實數,(x,y,z)是一個三維向量,四元數的基底為(1,i,j,k),則 Q = w + xi + yj + zk;四元數是複數在四維空間的推廣,於是可以認為i,j,k是四元數的虛單位。
     尤拉證明了任何旋轉都可以通過對一個軸的單一旋轉來表示,因此方向可以分解為一個角度(θ)+軸(n),可能有人和我一樣以為osg:: Quat(x,y,z,w)就是沿著軸(x,y,z)正向看去逆時針旋轉w角度(正向是從原點指向點(x,y,z)的向量的方向)但是,這是不對的。尤拉認為這個角度和軸不是簡單的放在四元數中,他們的關係應該如下:
                              q = [ cos(θ/2) , sin(θ/2)n ] = [ cos(θ/2), ( sin(θ/2)x, sin(θ/2)y, sin(θ/2)z ) ]
    四元數的標量部分為cos(θ/2),即把旋轉角的一半的餘弦值作為四元數的標量部分;把旋轉角的一半的正弦值和這個旋轉軸數乘以後得到的向量作為四元數的向量部分。而osg:: Quat在處理時將標量部分放在了最後,上面q用在osg中用osg:: Quat表示為:
                              q = [ sin(θ/2)n , cos(θ/2) ] = [ ( sin(θ/2)x, sin(θ/2)y, sin(θ/2)z ) ,cos(θ/2) ]
即在osg:: Quat中,它的成員變數_v[3]表示的是四元數的標量部分,因為餘弦函式的值域是有界閉區間[-1,1],所以看來_v[3]的值是介於[-1,1]區間上的,看osg:: Quat的一個成員函式makeRotate:

void Quat::makeRotate( value_type angle, value_type x, value_type y, value_type z )
{
    const value_type epsilon = 0.0000001;

    value_type length = sqrt( x*x + y*y + z*z );
    if (length < epsilon)
    {
        // ~zero length axis, so reset rotation to zero.
        *this = Quat();
        return;
    }

    value_type inversenorm  = 1.0/length;            //等會用於單位化旋轉軸
    value_type coshalfangle = cos( 0.5*angle );      //旋轉角一半的餘弦,用於實部
    value_type sinhalfangle = sin( 0.5*angle );      //旋轉角一半的正弦

    _v[0] = x * sinhalfangle * inversenorm;
    _v[1] = y * sinhalfangle * inversenorm;
    _v[2] = z * sinhalfangle * inversenorm;          //旋轉軸被單位化
    _v[3] = coshalfangle;
}
函式最後一句 "_v[3] = coshalfangle;" 說明了osg:: Quat對實部處理的這個事實,而同時,旋轉軸被單位化,再乘以一個值域有界為[-1,1]的正弦值,所以虛部每一個分量都介於[-1,1]之間。通過上述處理,可以將一個旋轉角,一個旋轉軸轉化為一個四元數。

再看看getRotate這個函式,怎樣從一個四元數得到它的旋轉角度和轉軸?
void Quat::getRotate( value_type& angle, value_type& x, value_type& y, value_type& z ) const
{
    value_type sinhalfangle = sqrt( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] );

    angle = 2.0 * atan2( sinhalfangle, _v[3] );
    if(sinhalfangle)
    {
        x = _v[0] / sinhalfangle;
        y = _v[1] / sinhalfangle;
        z = _v[2] / sinhalfangle;
    }
    else
    {
        x = 0.0;
        y = 0.0;
        z = 1.0;
    }

}

程式碼中第一句 "sqrt( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] )" 為什麼會是旋轉角一半的正弦值,看看剛才makeRotate的時候是怎麼處理過的:
    _v[0] = x * sinhalfangle * inversenorm;
    _v[1] = y * sinhalfangle * inversenorm;
    _v[2] = z * sinhalfangle * inversenorm;

代入上式,提取公因子sinhalfangle,可以發現正確。因為向量部分已經單位化了,所以可以直接得到時sin(angle/2)。事實上,_v[3]就是cos(angle/2),所以也可以
sin(angle/2) = sqrt(1 - _v[3]*_v[3]),_v[3]就是cos(angle/2),所以angle = 2 * acos(_v[3]),osg:: Quat中旋轉角angle的得到比較迂迴,它求得coshalfangle/sinhalfangle的反正切,即得angle的一半。求旋轉軸的時候分別給_v[0],_v[1],_v[2]除以sinhalfangle得到單位化後的旋轉軸。



四元數的運演算法則:i*i = j*j = k*k = i*j*k = -1;
                  ij = k; ji = -k;
                  jk = i; kj = -i;
                  ki = j; ik = -j;
大家可以用上面的法則推倒一下osg:: Quat中四元數的乘法,發現結果是正確的^^,乘法的時候,osg:: Quat是將實部放在最後一個分量_v[3]上的,有四元數的共軛:
inline Quat conj () const   {  return Quat( -_v[0], -_v[1], -_v[2], _v[3] ); }可以進一步看出第四個分量是實部,歡迎討論,批評指正。

相關推薦

OSG 導航俯仰橫滾

osg:: Quat的心得:      先介紹四元數:Q = [w,(x,y,z)]被定義為一個四元數,w為一個實數,(x,y,z)是一個三維向量,四元數的基底為(1,i,j,k),則 Q = w + xi + yj + zk;四元數是複數在四維空間的推廣,於是可以認為i,j,k是四元數的虛單位。      

線性篩函式與莫比烏斯函式 模板

#include<bits/stdc++.h> using namespace std; const int MAXN = 1e5+1; int prime[MAXN]; //素數 i

[luoguP2045] 方格取加強版最小費用最大流

col pid opened empty spl amp turn define aps 傳送門 水題 ——代碼 1 #include <queue> 2 #include <cstdio>

金融據指標歷史移動波動率均值

cnblogs ots port 1-1 art his ima 技術分享 img 1.導入函數 import numpy as np import pandas as pd import matplotlib.pyplot as plt import tushare a

代碼用於分行指定表格背景顏色

tin post back -c blog ron str body idt <style>.table-container{ width:800px;}tr.odd{background: #EDE4D4 !important;}tr.odd td.sor

MySQL 誤操作後據恢復update,delete忘加where條件

ima 數據完整性 rds 童鞋 sign server 段落 服務 字段 在數據庫日常維護中,開發人員是最讓人頭痛的,很多時候都會由於SQL語句寫的有問題導致服務器出問題,導致資源耗盡。最危險的操作就是在做DML操作的時候忘加where條件,導致全表更新,這是作為

限制輸入字符通用方法漢字占2位英符占1位

bsp else length har 變量名 limit array 數通 arr (待完善補充) checkLimitCharacterLength(itemName, length, parentObj) { //校驗字符長度(變量名,限制字符數,變量所屬的對象)

大資料之scala --- 模式匹配變數宣告模式樣例類函式泛型型變逆變隱式轉換隱式引數

一、模式匹配:當滿足case條件,就終止 ---------------------------------------------------------- 1.更好的switch var x = '9'; x match{ case

以後綴名為分類把檔案分別儲存到組裡朋友的一道簡單面試題

<?php $dir = scandir('C:\Users\Administrator\Desktop\images'); echo '<pre>'; // print_r($dir); $gif = array(); $png = array(); $jpg = array()

[] webpack之前端效能優化史上最全不斷更新中。。。

最近在用webpack優化首屏載入效能,通過幾種外掛之後我們上線前後的速度快了一倍,在此就簡單的分享下吧,先上個優化前後首屏渲染的對比圖。 可以看到總下載時間從3800ms縮短到1600ms。 我們在用webpack時一般都會選擇多入口檔案吧,為的就是將自己的原始碼跟第三方庫程式碼分離。這是之前的程式

全導方向導微分全微分梯度

學習到機器學習線性迴歸和邏輯迴歸時遇到了梯度下降演算法,然後順著扯出了一堆高數的相關概念理論:導數、偏導數、全微分、方向導數、梯度,重新回顧它們之間的一些關係,從網上和教材中摘錄相關知識點。 這段是我的簡單總結,如果看不懂沒關係,先看下面的定義 通過函式的極限定義出導數

CodeForces 482C Game with Strings 概率+狀壓DP 好題* 第百篇博文紀念

#include<bits/stdc++.h> using namespace std; #define debug puts("YES"); #define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++) #def

矩陣取遊戲noip2006c++ BigInteger的第一次運用---重點!!

今下午對c++BigInteger進行了初步的瞭解 同時,經過這次,我才深深的體會到了c++的靈活之處 1.對Biginteger的初步認識 2.對c++一些關鍵字的初步認識 3.對vector的一點長進和對這些容器的感覺整體框架加深 4.對operator的認識又加深了

方向倒數梯度

知乎連結 導數: 導數不僅僅表示該點切線的斜率,還反應了函式在該點的變化率。 偏導數: 偏導數僅僅是表示某點在x方向的導數和再y軸方向的導數。 這反應了偏導數的侷限性,僅僅是多元函式沿著座標軸的變化率,但是如上圖,在M0點處存在很多方向的偏導數(並不僅僅x和y方向

Java按位元組擷取字串防止中文被截成一半

Web應用程式在瀏覽器中顯示字串時,由於顯示長度的限制,常常需要將字串擷取後再進行顯示。 但目前很多流行的語言,如C#、Java內部採用的都是 Unicode 16(UCS2)編碼,在這種編碼中所有的字元都是兩個字元,因此,如果要擷取的字串是中、英文、數字混合的,就會產生問

Java8 LocalDateTime獲取時間戳毫秒/秒、LocalDateTime與String、Date與LocalDateTime

本文目前提供:LocalDateTime獲取時間戳(毫秒/秒)、LocalDateTime與String互轉、Date與LocalDateTime互轉 文中都使用的時區都是東8區,也就是北京時間。這是為了防止伺服器設定時區錯誤時導致時間不對,如果您是其他時區,請自行修改

cartographer輸出姿態ROS中

目的: 將cartographer輸出位姿(/tf)中四元數轉換成尤拉角(姿態角)輸出(C++語言) 實現如下: 首先在cartographer_ros/node.h中添加發布器宣告 ::ros::Publisher rpy_publisher; cartog

旋轉矩陣 軸

引言 我們日常生活的空間是三維的,因此我們生來就習慣於空間的運動。三維空間由三個軸組成,所以一個空間點的位置可以由3個座標指定。不過,我們現在要考慮剛體,它不光有位置,還有自身的姿態。以下,就是對剛體姿態的相關學習的筆記。 旋轉矩陣 表示座標系`O-x'y'z'`中

相機座標系與的轉換

今天,專案中利用aruco來識別二維碼來確定相機姿態,我就詳細研究了一下相機座標系。 (一)相機座標系 (二)如何在ROS中進行四元數和尤拉角轉化 將geometry_msgs::Quaternion轉化為tf::Quaternion型別 tf

旋轉矩陣 比較

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!