Unity3D學習筆記(八):四元素和書籍推薦
阿新 • • 發佈:2019-02-11
col 所有 sele super project ons 描述 直觀 gen
在Unity中,因為所有表示旋轉的四元數都是標準四元數,模長均為1,所以四元素的逆 = 共軛四元數
四元數讓向量旋轉:
四元數不僅可以旋轉點,還可以旋轉向量
書籍推薦:
3D數學基礎:圖形與遊戲開發——遊戲軟件開發專家系列(美)鄧恩 Unity Shader入門精要 馮樂樂(92年) 數據結構(Python語言描述) 數據結構、算法與應用(C++語言描述) 算法導論 第3版 黑客與畫家 程序員生存之道 流體力學:八叉數空間劃分四元數的幾個概念: 四元數的模長:Mathf.Sqrt(x^2 + y^2 + z^2 + w^2) 標準四元數:模長為1的四元數叫標準四元數:在Unity中所有用來表示旋轉的四元數都是標準四元數 單位四元數:[0,0,0,1],單位四元數表示無旋轉,Quaternion.identity 共軛四元數:讓原四元數虛數部分取負,讓原四元數反向旋轉,Unity中沒有共軛四元數 四元數 * 共軛四元數 = 單位四元數 四元數的逆:類似求導, 四元素的逆 = 共軛四元數 / 四元數的模長,即q-1 = *q / |q|
using System.Collections; using System.Collections.Generic; using UnityEngine; public class RotateVector : MonoBehaviour { // Use this for initialization void Start () { Vector3 dir = new Vector3(1四元數和歐拉角的優缺點: 1、歐拉角的優點: (1)、可以同時繞著三根軸一起旋轉 (2)、歐拉角節省內存,節省33.3333%的內存 (3)、直觀 2、歐拉角的缺點: (1)、萬向節死鎖 (2)、誤差大 1、四元數的優點: (1)、沒有萬向節死鎖 (2)、誤差小 (3)、可以繞任意一根軸旋轉 2、四元數的缺點: (1)、只能一根一根軸旋轉 (2)、比歐拉角多了33.3333%的內存 (3)、不直觀 鎖可以固定遊戲物體的檢視面板,方便把其他遊戲物體拖拽進來 models和prefabs的區別 models模型拖到場景,再拖回資源,可以變成預制體 四方連續,向四周重復地連續和延伸擴展而成的圖案形式。 二方連續,向上下或左右兩個方向反復連續而形成的紋樣。 世界坐標系轉屏幕坐標系 Vector2 screenPos = Camera.main.WorldToScreenPoint(target.position); 屏幕坐標系轉世界坐標系 Vector3 worldPos = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width, Screen.height, -Camera.main.transform.position.z));,0,1); Debug.DrawLine(Vector3.zero,dir,Color.red,1000); //單位四元數表示無旋轉 Debug.Log(Quaternion.identity); //四元數的逆 Quaternion q = Quaternion.AngleAxis(90, Vector3.up); Quaternion tempQ = Quaternion.Inverse(q); Debug.Log(q); Debug.Log(tempQ); //旋轉四元數Quaternion rotateQ = Quaternion.AngleAxis(45, Vector3.up); Vector3 newVector = rotateQ * dir; Debug.DrawLine(Vector3.zero, newVector, Color.green, 1000); //自己寫一個RotationAround //RotateAround(Vector3 point, Vector3 axis, float angle); } // Update is called once per frame void Update () { } }
using System.Collections; using System.Collections.Generic; using UnityEngine; public class RotateAroundScript : MonoBehaviour { public Transform sphere; public float rotateSpeed = 1; // Use this for initialization void Start () { } // Update is called once per frame void Update () { //調用RotateAround RotateAround(sphere.position, Vector3.up, rotateSpeed); } public void myRotateAround(Vector3 point, Vector3 axis, float angle) { Vector3 A = transform.position - point; //Vector3 n = Vector3.Project(); //Vector3.Dot(axis, A) = | n | * axis.magnitude; //| n | = Vector3.Dot(axis, A) / axis.magnitude; //Vector3 n = axis.normalized * | n |; Vector3 n = axis.normalized * Vector3.Dot(axis, A) / axis.magnitude; Vector3 a = A - n; Quaternion q = Quaternion.AngleAxis(angle, axis); Vector3 b = q * a; } }
復習
using System.Collections; using System.Collections.Generic; using UnityEngine; public class w06d4 : MonoBehaviour { public Transform target; public Vector3 cubeSize; //歐拉角是如何表示旋轉的 //使用x y z來表示旋轉 x表示繞x軸旋轉多少度 y表示繞y軸旋轉多少度 z表示繞z軸旋轉多少度 //四元數是如何表示旋轉的 //使用x y z w來表示旋轉 通過軸角對來表示旋轉 n軸轉45度 x = n.x * sin<theta/2> , y = n.y * sin<theta/2>, z = n.z * sin<theta/2>, w = cos<theta/2> //歐拉角和四元數的優缺點 //歐拉角 // 優點: 直觀,容易理解 // 缺點: 有萬向節鎖 // 只能繞固定軸旋轉 // 不能實現旋轉的平滑差值 //四元數 // 優點: 可以實現任何角度的旋轉 // 可以實現旋轉疊加 // 沒有萬向節鎖 、 // 可以繞任意軸旋轉 // 可以實現旋轉的平滑差值 // 缺點: 不直觀,不容易理解 //API //使當前遊戲物體的旋轉變為 繞x軸旋轉90 //1)、使用歐拉角的形式賦值 //transform.eulerAngles = new Vector3(90, 0, 0); // 使用四元數的形式賦值 //transform.rotation = Quaternion.AngleAxis(90, Vector3.right); //2)、使當前遊戲物體直接看向目標 transform.LookAt(target); transform.rotation = Quaternion.LookRotation(target.position - transform.position); //3)、使當前遊戲物體緩緩看向目標 transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(target.position - transform.position), 1/Quaternion.Angle(transform.rotation, Quaternion.LookRotation(target.position - transform.position))); //4)、把一個歐拉角轉換為四元數 transform.rotation = Quaternion.Euler(0, 45, 0); //5)、使用鼠標的水平軸值控制當前物體旋轉(使用四元數疊加) float mouseX = Input.GetAxis("Mouse X"); //自身的 繞Y軸轉 XX 度 transform.rotation *= Quaternion.Euler(0, mouseX, 0); //世界的 繞Y軸轉 XX 度 transform.rotation = Quaternion.Euler(0, mouseX, 0) * transform.rotation; void Start () { transform.rotation = Quaternion.AngleAxis(90, Vector3.right); transform.eulerAngles = new Vector3(90, 0, 0); transform.LookAt(target); transform.rotation = Quaternion.LookRotation(target.position - transform.position); transform.rotation = Quaternion.Euler(0, 45, 0); } void Update () { transform.rotation = Quaternion.Slerp( transform.rotation, Quaternion.LookRotation(target.position - transform.position), 1 / Quaternion.Angle(transform.rotation, Quaternion.LookRotation(target.position - transform.position))); float mouseX = Input.GetAxis("Mouse X"); // 自身的 繞Y軸轉 XX 度 transform.rotation *= Quaternion.Euler(0, mouseX, 0); // 世界的 繞Y軸轉 XX 度 transform.rotation = Quaternion.Euler(0, mouseX, 0) * transform.rotation; } private void OnDrawGizmos() { Gizmos.color = new Color(0, 1, 0, 0.2f); Gizmos.DrawSphere(transform.position, 10); } private void OnDrawGizmosSelected() { Gizmos.color = Color.red; Gizmos.DrawCube(transform.position, cubeSize); } }
Unity3D學習筆記(八):四元素和書籍推薦