Unity三维数学 —— 欧拉角与四元数

一、欧拉角

1、欧拉角 X、Z 沿自身坐标系旋转,Y沿世界坐标系旋转

2、API:Vector3 eulerAng = gameObject.transform.eulerAngles;

// 欧拉角没有方向大小等概念,其中的x,y,z 只表示沿各个轴上的旋转角度
Vector3 euler = gameObject.transform.eulerAngles;

// 表示将当前的欧拉角在x轴上增加1度
gameObject.transform.eulerAngles += new Vector3(1, 0, 0);

二、四元数

(一)、四元数的基本知识

1、四元数在3D图形学中表示旋转,由一个三维向量(x、y、z)和一个标量(w)组成。即:(x , y , z , w)。

2、若旋转轴用 V 表示,旋转角度为 rad (用弧度来表示),则表示成四元数时,其分量为:

       x = sin ( rad / 2 ) *V.x  ; y = sin ( rad / 2 ) *V.y  ;z = sin ( rad / 2 ) *V.z  ;w = cos (rad / 2)

即轴角到四元数:

给定一个单位长度的旋转轴 (x, y, z) 和一个角度 θ 。对应的四元数为:

           {\color{Red} ((x,y,z)*sin(\theta/2) ,cos(\theta/2))}

3、 x ,y, z, w 的取值范围是 -1 到 1 。

4、Unity中的 Quaternion.identity 的值,表示旋转0度

private void Start()
{
    Debug.Log("Quaternion.identity = " + Quaternion.identity);
    Debug.Log("Quaternion.identity.x = " + Quaternion.identity.x);
    Debug.Log("Quaternion.identity.y = " + Quaternion.identity.y);
    Debug.Log("Quaternion.identity.z = " + Quaternion.identity.z);
    Debug.Log("Quaternion.identity.w = " + Quaternion.identity.w);
}

结果如下:

(二)、应用

1、四元数在Unity中的基本应用

  • 四元数都是绕其自身的坐标系来进行旋转的
  • API 中表示四元数为:Quaternion qt = this.transform.rotation 
  • 两个四元数相乘可以组合旋转效果(四元数不可以相加
    // rotation01和rotation02效果相同,都表示旋转50度。
    Quaternion rotation01 = Quaternion.Euler(0, 30, 0) * Quaternion.Euler(0, 20, 0);
    Quaternion rotation02 = Quaternion.Euler(0, 50, 0);
    

     

  • 欧拉角转换成四元数的API,如:this.transform.rotation = Quaternion.Euler(0, 60, 0); 

2、用四元数表示来让物体的旋转

private void OnGUI()
{
    if (GUILayout.RepeatButton("绕X轴旋转"))
    {
        this.transform.rotation *= Quaternion.Euler(2, 0, 0);

        transform.Rotate(new Vector3(2, 0, 0));//其内部也是调用四元数来实现的
    }
    if (GUILayout.RepeatButton("绕Y轴旋转"))
    {
        this.transform.rotation *= Quaternion.Euler(0, 2, 0);

        transform.Rotate(new Vector3(0, 2, 0));
    }
    if (GUILayout.RepeatButton("绕Z轴旋转"))
    {
        this.transform.rotation *= Quaternion.Euler(0, 0, 2);

        transform.Rotate(new Vector3(0, 0, 2));
    }
}

3、四元数与向量来控制物体的运动

(1)、四元数左乘向量,表示将该向量按照四元数表示的角度旋转。当角度为正值时,表示顺时针;为负值时,表示逆时针。如下所示:

Vector3 point = new Vector3(0, 0, 6);
// newPoint为将point点绕Y轴旋转30度,所得到的点
Vector3 newPoint = Quaternion.Euler(0, 30, 0) * point;

(2)、对一个物体进行平移和旋转

Debug.DrawLine(this.transform.position, vect01);
if (Input.GetMouseButtonDown(0))
{
    // vect01 相当于该物体在当前的位置沿着(0,0,6)移动后的位置
    // vect02 相当于将vect01所在的位置绕Y轴顺时针旋转30度后的位置
    vect01 = gameObject.transform.position + new Vector3(0, 0, 6);
    vect02 = this.transform.position + Quaternion.Euler(0, 30, 0) * new Vector3(0, 0, 6);
}

4、四元数的API

//1、欧拉角----> 四元数
Quaternion qt01 = Quaternion.Euler(new Vector3(0, 60, 0));

//2、四元数----> 欧拉角
Quaternion qt02 = this.transform.rotation;
Vector3 euler = qt02.eulerAngles; // 将四元数转换成欧拉角

// 3、轴角:将当前物体沿y轴旋转60度.等效于: Quaternion.Euler(0,60,0)
this.transform.rotation = Quaternion.AngleAxis(60, Vector3.up);

// 4、注视旋转:Z轴指向一个方向(为第一个参数),物体的position是不变的
Quaternion qt03 = Quaternion.LookRotation(Vector3.up);

// 5、注视旋转,相当于 LookRotation
this.transform.LookAt(Vector3.zero, Vector3.up);

// 6、使用Lerp来控制旋转的速度,速度不是匀速的
Quaternion.Lerp(this.transform.rotation, Quaternion.Euler(0, 6, 0), 0.1f);

// 7、匀速旋转
Quaternion.RotateTowards(this.transform.rotation, Quaternion.Euler(0, 60, 0), 0.1f);

//8、X轴注视旋转,让物体X轴始终指向:物体位置到v1所在的向量
this.transform.right = v1 - this.transform.position;

// 9、当前物体绕Y轴向上,且在(2,0,6)点 ,旋转90度。若不指定点,则Y轴向上可以有很多个位置。
this.transform.RotateAround(new Vector3(2,0,6), Vector3.up, 90f);

5、注视旋转的讲解

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Move : MonoBehaviour 
{
    Transform s1, s2, s3, s4,tfCube;
    Quaternion qt01;

    void Start () {
        s1 = GameObject.Find("Sphere1").GetComponent<Transform>();
        s2 = GameObject.Find("Sphere2").GetComponent<Transform>();
        s3 = GameObject.Find("Sphere3").GetComponent<Transform>();
        s4 = GameObject.Find("Sphere4").GetComponent<Transform>();
        tfCube = GameObject.Find("Cube").GetComponent<Transform>();      
		
	}
    private void OnGUI()
    {
        if (GUILayout.RepeatButton("Rotate"))
        {
            /* 让立方体注视球(立方体----->球)进行旋转,即让立方体的Z轴指向球
             * 所以方向为: s3.position-tfCube.position,
             * 运行的结果为立方体的position不变,但是Z轴的朝向变了,Z轴的位置由
             * 原来的方位变成指向球所在的位置。
             */
            Vector3 dir = s3.position - tfCube.position;//求方向
            qt01 = Quaternion.LookRotation(dir);  //将注视的方向传递给函数,返回四元数
            //tfCube.rotation = qt01; //将四元数所表示的旋转值赋给立方体
            tfCube.rotation = Quaternion.Lerp(tfCube.rotation, qt01, 0.1f);
        }
    }
}

运行结果如下:蓝色为Z轴

   


参考资料

[1]  【Unity技巧】四元数(Quaternion)和旋转

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值