Unity3D学习笔记(八):四元素和书籍推荐

书籍推荐:

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|
在Unity中,因为所有表示旋转的四元数都是标准四元数,模长均为1,所以四元素的逆 = 共轭四元数
 
四元数让向量旋转:
四元数不仅可以旋转点,还可以旋转向量
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RotateVector : MonoBehaviour {
       // Use this for initialization
       void Start () {
        Vector3 dir = new Vector3(1,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 () {
              
       }
}
四元数和欧拉角的优缺点:
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));
 
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);
    }

}
 

猜你喜欢

转载自www.cnblogs.com/ciaowoo/p/10362882.html