三維空間旋轉(zhuǎn) 歐拉角、四元數(shù)

歐拉角:三個(gè)角度確定物體旋轉(zhuǎn)狀態(tài) https://www.bilibili.com/video/BV12s411g7gU?p=163

優(yōu)點(diǎn)1:三個(gè)數(shù)字表達(dá)物體的旋轉(zhuǎn)狀態(tài),占用空間小
優(yōu)點(diǎn)2:沿坐標(biāo)軸旋轉(zhuǎn)角度為角度,符合人的思維方式
優(yōu)點(diǎn)3:三個(gè)數(shù)字都是合法旋轉(zhuǎn)角度,不像四元素存在非法旋轉(zhuǎn)數(shù)字
缺點(diǎn)1:表達(dá)方式不唯一!eg:(0,5,0) (0,365,0)表示同一個(gè)旋轉(zhuǎn)狀態(tài) (250,0,0) 和(290,180,180)表示同一個(gè)旋轉(zhuǎn)狀態(tài) (為了解決這個(gè)問(wèn)題Unity 刻意規(guī)定x y z的旋轉(zhuǎn)角度范圍 -90<x<90、 0<y<360 、0<z<360)
缺點(diǎn)2:萬(wàn)向節(jié)死鎖 x軸旋轉(zhuǎn)90度或者-90度 時(shí),自身坐標(biāo)系的z軸和世界坐標(biāo)系的Y軸重合,此時(shí)沿Y軸旋轉(zhuǎn)和沿z軸旋轉(zhuǎn)效果相同(失去了一個(gè)方向上的旋轉(zhuǎn)自由度) (特殊說(shuō)明:物體的歐拉角旋轉(zhuǎn) x:沿自身坐標(biāo)系 Y:沿世界坐標(biāo)系 Z:沿自生坐標(biāo)系)
Vector3 是一個(gè)有 x y x三個(gè)float變量的結(jié)構(gòu)體 不代表向量  歐拉角 不是向量千萬(wàn)不能位置向量混淆!!!
       //x軸旋轉(zhuǎn)到10°  y軸旋轉(zhuǎn)到20°  z軸旋轉(zhuǎn)到30°
       this.transform.eulerAngles = new Vector3(10,20,30);
       //+= 表示 x y z 方向上的角度分別相加
       //x 軸上的旋轉(zhuǎn)角度 在原來(lái)的基礎(chǔ)上+10° y軸在原來(lái)的基礎(chǔ)上+20° z軸在原來(lái)的基礎(chǔ)上+30°
       this.transform.eulerAngles +=  new Vector3(10,20,30);

       //Vector3.left = new Vector3(-1,0,0);
       this.transform.eulerAngles = Vector3.left;
       //Vector3.forward = new Vector3(0,0,1);
       this.transform.eulerAngles = Vector3.forward;
       //Vector3.up = new Vector3(0,1,0);
       this.transform.eulerAngles = Vector3.up;

四元數(shù):軸角模式旋轉(zhuǎn)確定旋轉(zhuǎn)狀態(tài)https://www.bilibili.com/video/BV12s411g7gU?p=164&spm_id_from=pageDriver

旋轉(zhuǎn)軸V 旋轉(zhuǎn)弧度 θ (計(jì)算得到的x y z w 值都是-1到1之間的數(shù))
x = sin(θ/2) * V.x;
y = sin(θ/2) * V.y;
z = sin(θ/2) * V.z;
w = cos(θ/2);

        //數(shù)學(xué)原理上的寫(xiě)法
        //旋轉(zhuǎn)軸
        Vector3 axis = Vector3.up;
        //旋轉(zhuǎn)弧度
        float rad = 50 * Mathf.Deg2Rad;
        //旋轉(zhuǎn)軸在x上的分量
        float x = Mathf.Sin(rad / 2) * axis.x;
        //旋轉(zhuǎn)軸在y上的分量
        float y = Mathf.Sin(rad / 2) * axis.y;
        //旋轉(zhuǎn)軸在z上的分量
        float z = Mathf.Sin(rad / 2) * axis.z;
        float w = Mathf.Cos(rad / 2);
        Quaternion qt = new Quaternion(x,y,z,w);
        this.transform.rotation = qt;
//歐拉角  轉(zhuǎn) 成四元數(shù) 使用
this.transform.rotation = Quaternion.Euler(0, 50, 0);
//四元數(shù)和歐拉角組合旋轉(zhuǎn)
this.transform.rotation = Quaternion.Euler(0, 50, 0) * Quaternion.Euler(10,10,10);
//上面的乘法運(yùn)算結(jié)果等于下面的內(nèi)容
//兩個(gè)四元數(shù)相乘 表示兩個(gè)量的歐拉角x y z 分別相加
  this.transform.rotation = Quaternion.Euler(10, 60, 10);
       

四元數(shù):旋轉(zhuǎn)向量

//一個(gè)向量 沿y軸旋轉(zhuǎn)10°  
 Vector3 newPos = Quaternion.Euler(0,10,0) * this.transform.position;
        //1.歐拉角 -> 四元數(shù)  
       Quaternion qt = Quaternion.Euler(角度值);

        //2.四元數(shù) -> 歐拉角
        Quaternion qt = this.transform.rotation;
        Vector3 euler = qt.eulerAngles;

        //3.軸、角 旋轉(zhuǎn)模式
        this.transform.rotation = Quaternion.AngleAxis(角度值, 軸向量);
        //例如:當(dāng)前物體沿Y軸旋轉(zhuǎn)30度
        this.transform.rotation = Quaternion.AngleAxis(30, Vector3.up);
        //特殊:沿 X軸 旋轉(zhuǎn)10°(簡(jiǎn)單寫(xiě)法)
        this.transform.rotation = Quaternion.Euler(10, 0,0);
        //特殊:沿 Y軸 旋轉(zhuǎn)10°(簡(jiǎn)單寫(xiě)法)
        this.transform.rotation = Quaternion.Euler(0, 10,0);
        //特殊:沿 Z軸 旋轉(zhuǎn)10°(簡(jiǎn)單寫(xiě)法)
        this.transform.rotation = Quaternion.Euler(0, 0,10);

        //4 計(jì)算兩個(gè)四元數(shù)的夾角
         float angle = Quaternion.Angle(this.transform.rotation, tf.rotation);
        
        //5.注視旋轉(zhuǎn)模式 (注視旋轉(zhuǎn)默認(rèn)就是Z軸注視旋轉(zhuǎn))
        //5.1 直接改變當(dāng)前物體的旋轉(zhuǎn)角度 沒(méi)有過(guò)度旋轉(zhuǎn)動(dòng)畫(huà)
        this.transform.LookAt(被注視物體的transform)
       //5.2 注視旋轉(zhuǎn)
       // 第一步計(jì)算目標(biāo)點(diǎn)向量
      Vector3 vect = tf.transform.position(被注視對(duì)象的向量)  -  this.transform.position(當(dāng)前物體向量);
      this.transform.rotation = Quaternion.LookRotation(vect);//注視旋轉(zhuǎn)
      
      //6.旋轉(zhuǎn)過(guò)度動(dòng)畫(huà)
      Vector3 vect = tf.transform.position(被注視對(duì)象的向量)  -  this.transform.position(當(dāng)前物體向量);//獲取目標(biāo)的向量
      Quaternion qt = Quaternion.LookRotation(vect);//目標(biāo)旋轉(zhuǎn)四元數(shù)
    //6.1勻速變化旋轉(zhuǎn)
      this.transform.rotation = Quaternion.RotateTowards(this.transform.rotation,qt,0.1);
    
      //6.2 差值Lerp  先快后慢旋轉(zhuǎn)
     //(特點(diǎn):按百分比無(wú)限接近無(wú)法達(dá)到終點(diǎn),需要設(shè)置終點(diǎn)閥值)
     this.transform.rotation = Quaternion.Lerp(this.transform.rotation,qt,0.1);
      //計(jì)算旋轉(zhuǎn)四元數(shù) 和 目標(biāo)四元數(shù)之前的夾角
     float angle = Quaternion.Angle(this.transform.rotation,qt);
      if(angle < 1)
      { 
           this.transform.rotation = qt;
      }
      //7 獲取一個(gè)與世界坐標(biāo)系一樣的四元數(shù)
      //(就是不做任何旋轉(zhuǎn),經(jīng)常配合預(yù)制體創(chuàng)建新GameObject使用)
     Quaternion qt = Quaternion.identity;
        
    //8. 從一個(gè)向量位置  轉(zhuǎn)到目標(biāo)向量位置
    //先計(jì)算目標(biāo)向量
      Vector3 vect = tf.transform.position(被注視對(duì)象的向量)  -  this.transform.position(當(dāng)前物體向量);
    //使用FromToRotation 將X軸正方向 轉(zhuǎn)到 正對(duì)著物體
    Quaternion qt = Quaternion.FromToRotation(Vector3.right, vect);
    //再使用lerp 做旋轉(zhuǎn)過(guò)度動(dòng)畫(huà)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 旋轉(zhuǎn)矩陣 點(diǎn),向量,坐標(biāo)系 剛體不光有位置,還有自身的姿態(tài).位置是指剛體在空間中的哪個(gè)地方,姿態(tài)是指剛體的朝向. ...
    南衍兒閱讀 4,385評(píng)論 0 2
  • 1 前言 OpenGL渲染3D模型離不開(kāi)空間幾何的數(shù)學(xué)理論知識(shí),而本篇文章的目的就是對(duì)空間幾何進(jìn)行簡(jiǎn)單的介紹,并對(duì)...
    RichardJieChen閱讀 7,557評(píng)論 1 11
  • 概述 又研究了將近兩個(gè)星期的3D圖形到了我最想研究的地方了,因?yàn)闅W拉角與四元數(shù)的原因?qū)е翺penGL ES的研究進(jìn)...
    神經(jīng)騷棟閱讀 8,042評(píng)論 12 40
  • 本文為個(gè)人筆記,查看原文請(qǐng)關(guān)注公眾號(hào):計(jì)算機(jī)視覺(jué)life 剛體:運(yùn)動(dòng)過(guò)程中不會(huì)產(chǎn)生形變的物體,運(yùn)動(dòng)過(guò)程中同一個(gè)向量...
    BlueBubbles閱讀 864評(píng)論 0 0
  • 萊昂哈德·歐拉用歐拉角來(lái)描述剛體在三維歐幾里得空間的取向。對(duì)于任何參考系,一個(gè)剛體的取向,是依照順序,從這參考系,...
    coldestheaven閱讀 520評(píng)論 0 1

友情鏈接更多精彩內(nèi)容