目录

三维数学 - Vector3

# 三维数学 - Vector3

  • 向量
    1. 什么是向量
    2. 向量的形式
    3. 向量的大小
    4. 向量的方向
  • 向量运算
    1. 向量相减
    2. 向量相加
    3. 向量与标量的乘除法
    4. 点乘
    5. 叉乘
  • 三角函数
    1. 角的度量单位
    2. 三角函数
    3. 反三角函数
    4. 欧拉角
  • 常用属性与方法

# 向量

# 什么是向量

  • 一个数字列表,表示各维度上的有向位移。
  • 一个有大小、方向的物理量
    • 大小即为向量的模长
    • 方向即为空间中向量的指向
  • 可以表示物体的位置与方向

# 向量的形式

二维向量中的形式是(x,y),三维向量中的形式是(x,y,z)

# 向量的大小

  • 向量各分量的平方和的平方根
  • $\sqrt (x^2+y^2+z^2)$
  • API: float dis = vector.magnitude
    • 模的平方 vector.sqrMagnitude

# 向量的方向

  • 获取向量方向也称“标准化向量”或者“归一化向量”
  • 单位向量:大小为1的向量
  • 几何意义:将该向量拉长/缩短,使模长等于1
  • API:Vector3 v = vector.normalized;
    • v为vector的单位向量

# 向量相减

  • 等于各分量相减
  • 公式:[x1,y1,z1] - [x2,y2,z2] = [x1-x2,y1-y2,z1-z2]
  • 几何意义:向量a与b相减,结果理解为b的终点为起点,a的终点为终点,诞生一条新向量,方向由b指向a
  • 应用:计算两点间的距离和相对方向,可以用于制作抛射物,如子弹发射
public GameObject g;
private Vector3 v;

void Start()
{
	g = GameObject.Find("Cube");
    v = (g.transform.position - transform.position)
}
1
2
3
4
5
6
7
8

# 向量相加

  • 等于各分量相加和
  • 公式: [x1,y1,z1] + [x2,y2,z2] = [x1+x2,y1+y2,z1+z2]
  • 几何意义:向量a与b相加,平移使b的起点与a的终点重合,结果为以a的起点为起点,以b的终点为终点

# 向量的点乘

  • 公式:各分量乘积和
  • [x1,y1,z1]·[x2,y2,z2] = x1x2 + y1y2 + z1z2
  • 几何意义: $ab=|a||b|cos(a,b)$
  • 两个向量的单位向量相乘后,再乘以二者夹角的余弦值
  • API: float dot = Vector3.Dot(va,vb)
public float length_a,length_b;
public GameObject g;
void Start()
{
    length_a = this.transform.position.magnitude;
    length_b = g.transform.position.magnitude;

    Debug.Log(Vector3.Dot(this.transform.position.normalized, g.transform.position.normalized));
    Debug.Log("Angle is:"+Mathf.Acos((Vector3.Dot(this.transform.position, g.transform.position)) / (length_a * length_b))*Mathf.Rad2Deg);
}
1
2
3
4
5
6
7
8
9
10

# 向量的叉乘

  • 公式: [x1,y1,z1] * [x2,y2,z2] = [y1*z2 -z1*y2,z1*x2 - x1*z2, x1*y2 - y1*x2]

  • 几何意义:结果为两个向量所组成的面的垂直向量,模长为两向量模长乘积再乘夹角的正弦值

  • API:Vector v = Vector3.Cross(a,b)

  • 应用

    • 创建垂直于平面的向量

# 角的度量方式

角度与弧度换算: PI = 180° 1弧度 = 180° / PI 1角度 = PI / 180°

API: 弧度 = 角度 * Mathf.Deg2Rad 角度 = 弧度 * Mathf.Rad2Deg

# 三角函数

  • 已知一边一角,求另一边长
  • 对边: a, 角的对立边
  • 临边: b, 角的相邻边
  • 斜边: c, 角的斜边
  • 公式:
    1. 正弦 sin(x) = a / c
    2. 余弦 cos(x) = b / c
    3. 正切 tan(x) = a / b
  • API:
    1. Mathf.Sin(float radian)
    2. Mathf.Cos(float radian)
    3. Mathf.Tan(float radian)

# 欧拉角

  • 使用三个角度保存方位
  • X与Z沿自身坐标系旋转,Y沿世界坐标系
  • 优点:
    • 仅用三个数字表达方位,占空间小
    • 沿坐标轴旋转的单位是角度,符合人类思维
    • 任意三个数字都是合法的,不存在不合法的欧拉角
  • 万向节死锁
    • 游戏编译期间,代码操作X轴只能+-90°,当抵达极限值时,会发生万向节死锁
    • 即,Y与Z沿同一轴旋转
  • 范围:
    • X: 90~-90
    • Y: 0~360
    • Z: 0~360 切记,Unity中的物体欧拉角通过this.transform.eularAngles获取,类型为Vector 3,虽然与position一样是Vector 3类型,但欧拉角的x,y,z仅代表沿各轴旋转的角度,并没有方向的概念。

但由于欧拉角的X在转到+-90°时会发生万向节死锁,因此引入了一个新的概念 —— 四元数

# 四元数

Unity中提供了Quaternion工具类用于操作四元数计算,最简单地,我们可以通过Quaternion.Euler(0,30,0)表示为物体沿y轴旋转30°

我们在欧拉角计算中可以通过加法实现角度旋转,但我们并不能直接用欧拉角去加四元数

欧拉角加法
this.transform.eularAngles += new Vector3(1,0,0); 物体沿X轴旋转一度

四元数加法
this.transform.rotation *= Quaternion.Euler(1,0,0);

Quaternion r1 = Quaternion.Euler(0,30,0) * Quaternion.Euler(0,20,0)
Quaternion r2 = Quaternion.Euler(0,50,0)
r1的旋转与r2是一样的
1
2
3
4
5
6
7
8
9

# 补充

有时,我们只想知道对比俩向量的长度,可以直接用sqrMagnitude而不是magnitude,相比后者,前者不需要开方,可以节省性能。

# 常用方法

# Angle
  • 参数: 向量A,向量B
  • 作用:求出两个向量相交角的角度
# Distance
  • 参数: 向量A,向量B
  • 作用: 求出两个向量间的长度
# Lerp
  • 参数: 向量A,向量B,速度
  • 作用: 求出A和B向量间的线性插值,可用于做减速运动
  • 示例:
if (GUILayout.RepeatButton("按我"))
{
    this.transform.position = Vector3.Lerp(this.transform.position, new Vector3(0, 0, 10),0.1f);
}
1
2
3
4

A会逐渐接近B,但永远无法到达B,从而实现肉眼上的减速运动。

# MoveTowards
  • 参数: 向量A,向量B,速度X
  • 作用: A每次向B移动X距离,作用与Lerp类似,但会抵达终点
  • 示例:
if (GUILayout.RepeatButton("按我"))
{
    this.transform.position = Vector3.MoveTowards(this.transform.position, new Vector3(0, 0, 10), 0.1f);
}
1
2
3
4

这是匀速啊,但我想实现开头慢中间快末尾慢该怎么办呢? 我们可以使用AnimationCurve实现这种想法

public AnimationCurve curve;
public float x;
private void OnGUI()
{
    if (GUILayout.RepeatButton("按我"))
    {
        x += Time.deltaTime;
        this.transform.position = Vector3.MoveTowards(this.transform.position, new Vector3(0, 0, 10), curve.Evaluate(x));
    }
}
1
2
3
4
5
6
7
8
9
10
最近更新
01
基本知识
07-18
02
卷积神经网络识别图像
07-18
03
损失函数
07-18
更多文章>