Three-Dimensional Mathematics (2)

Euler angle 

Use the rotation angle of the object on the three rotation axes to save the orientation 

API:

Transform.eulerAngles : returns or sets the Euler angles of the object

Advantages :

1. Only use three numbers to express the orientation, occupying a small space

2. The unit of rotation along the coordinate axis is angle, which is in line with the way of thinking of people

3. Any three numbers are legal, and there are no illegal Euler angles

Disadvantages :

1. The expression of orientation is not unique : for an orientation, there are multiple Euler angle descriptions, so it is impossible to judge whether the angular displacements represented by multiple Euler angles are the same

For example:

  • Angle(0,5,0) vs Angle(0,365,0)
  • Angle(0,-5,0) and Angle(0,355,0)
  • Angle(250,0,0) and Angle(290,180,180)

In order to ensure that any orientation has only a unique representation, the Unity engine limits the angle range, that is, the rotation along the X axis is limited to between -90 and 90, and the rotation along the Y and Z axes is limited to between 0 and 360.

2. Gimbal deadlock :

  • When the object rotates ±90 degrees along the X axis, the Z axis of its own coordinate system will coincide with the Y axis of the world coordinate system. At this time, when it rotates along the Y or Z axis, it will lose a degree of freedom
  • In the case of universal joint deadlock, it is stipulated that all rotations around the vertical axis are completed along the Y axis, that is, the rotation of the Z axis is 0 at this time
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EulerDemo : MonoBehaviour
{
    private void OnGUI()
    {
        if (GUILayout.RepeatButton("沿x轴旋转"))
        {
            Vector3 pos = this.transform.position;
            //有方向(从世界原点指向当前位置),有大小(当前位置到世界原点的间距)
            //向量x,y,z,表示各个轴向上的有向位移

            Vector3 euler = this.transform.eulerAngles;
            //是向量类型,但没有方向和大小
            //欧拉角x,y,z表示各个轴上的旋转角度

            //各分量相加,欧拉角x增加1度
            this.transform.eulerAngles += new Vector3(1, 0, 0);
        }

        if (GUILayout.RepeatButton("沿y轴旋转"))
        {
            //this.transform.eulerAngles+=new Vector3(0,1,0);
            this.transform.eulerAngles += Vector3.up;
        }

        if (GUILayout.RepeatButton("沿z轴旋转"))
        {
            this.transform.eulerAngles += new Vector3(0, 0, 1);
            this.transform.eulerAngles += Vector3.forward;
        }
    }
}

Quaternion

Quaternion represents rotation in 3D graphics and consists of a three-dimensional vector (X/Y/Z) and a scalar (W) 

The axis of rotation is V, and the radian of rotation is 0. If represented by a quaternion, the four components are:

  • x=sin(0/2)*V.x
  • y=sin(0 /2)*Vy
  • z=sin(0 /2)*V.z
  • w=cos(0 /2)

The value range of X, Y, Z, W is -1~1

//旋转轴
Vector3 axis = Vector3.up;
//旋转弧度
float rad = 50 * Mathf.Deg2Rad;

Quaternion qt = new Quaternion();
qt.x = Mathf.Sin(rad / 2) * axis.x;
qt.y = Mathf.Sin(rad / 2) * axis.y;
qt.z = Mathf.Sin(rad / 2) * axis.z;
qt.w = Mathf.Cos(rad / 2);

this.transform.rotation = qt;

The above code can be simplified to

//旋转轴
Vector3 axis = Vector3.up;
//旋转弧度
float rad = 50 * Mathf.Deg2Rad;

this.transform.rotation = Quaternion.Euler(0, 50, 0);

API:

Quaternion.Euler(float x, float y, float z) : Returns a rotation that rotates z degrees around the z axis, x degrees around the x axis, and y degrees around the y axis (applied in that order)

private void OnGUI()
{

    if (GUILayout.Button("沿x轴旋转"))
    {
        this.transform.rotation *= Quaternion.Euler(1, 0, 0);
        //this.transform.Rotate(1, 0, 0);
    }

    if (GUILayout.Button("沿y轴旋转"))
    {
        this.transform.rotation *= Quaternion.Euler(0, 1, 0);
    }

    if (GUILayout.Button("沿z轴旋转"))
    {
        this.transform.rotation *= Quaternion.Euler(0, 0, 1);
    }
}

in

this.transform.rotation *= Quaternion.Euler(1, 0, 0);

Equivalent to

this.transform.Rotate(1, 0, 0);

Pros : avoid gimbal deadlock

Disadvantages :

  • Difficult to use, it is not recommended to modify a value individually
  • There is an illegal quaternion

basic operations 

1. Multiply with the vector : Multiply the vector by the quaternion to the left, which means to rotate the vector according to the angle represented by the quaternion 

Vector3 point = new Vector3(0, 0, 10);
Vector3 newPoint = Quaternion.Euler(0, 30, 0) * point;

  

 2. Multiply with quaternion : Multiplying two quaternions can combine the rotation effect

Quaternion rotation01 = Quaternion.Euler(0, 30, 0) * Quaternion.Euler(0, 20, 0);

 Equivalent to

Quaternion rotation02 = Quaternion.Euler(0, 50, 0);

Common APIs

Quaternion.LookRotation(Vector3 forward, Vector3 upwards= Vector3.up) ​:

forward direction to look
upwards vector defining the up direction

Principle: The Z axis will be aligned with forward, the X axis will be aligned with the cross product between forward and upwards, and the Y axis will be aligned with the cross product between Z and X 

public Transform target;

//当前物体注视target旋转
Vector3 dir = target.position - this.transform.position;
this.transform.rotation = Quaternion.LookRotation(dir);
//this.transform.LookAt(target);

Quaternion.Lerp(Quaternion a, Quaternion b, float t)

a start value, returned when t = 0
b end value, returned when t = 1
t interpolation ratio
public Transform target;

//差值旋转
Quaternion dir = Quaternion.LookRotation(target.position - this.transform.position);
this.transform.rotation = Quaternion.Lerp(this.transform.rotation, dir, 0.1f);
if (Quaternion.Angle(this.transform.rotation, dir) < 0.1f)
{
    this.transform.rotation = dir;
}

Quaternion.FromToRotation​(Vector3 fromDirection, Vector3 toDirection) : Creates a rotation from fromDirection to toDirection

public Transform target;

//x轴注视旋转
//this.transform.right = target.position - this.transform.position;
Quaternion dir = Quaternion.FromToRotation(Vector3.right, target.position - this.transform.position);
this.transform.rotation = dir;

Quaternion.AngleAxis(float angle, Vector3 axis) : Creates a rotation around axis by angle degrees

public Transform target;

//轴/角旋转
this.transform.rotation = Quaternion.AngleAxis(50, Vector3.up);

Guess you like

Origin blog.csdn.net/qq_53401568/article/details/128565058