这里可以补补课:Godot向量数学。这是为了理解shader的运算。
关于向量,需要考虑的一个重要点是它们仅表示 相对 方向和大小。没有一个向量的位置的概念。
向量表示方向和幅度。仅表示幅值的值称为 标量。
向量运算
var c = a + b #(2,5) + (3,1) = (5,6)
向量 * 标量
var c = a * 2 # (2,5) * 2 = (4,10)
var d = b / 3 # (3,6) /3 = (1,2)
移动 / 加法
向量可以表示具有大小和方向的任何量。典型的示例有:位置、速度、加速度和力。
在这幅图像中,在第一步的飞船有一个位置向量为(1,3)和一个速度向量为(2,1)。速度向量表示船舶每一步移动的距离。通过将速度加到当前位置,我们可以求出步骤2的位置。
朝向 / 减法
在这个场景中,您有一个坦克,希望它的炮塔指向机器人。从机器人的位置减去坦克的位置就得到了从坦克指向机器人的向量。
单位向量 / 归一化
一个大小为1的向量称为单位向量。
归一化向量意味着在保持其方向的同时将其长度减少到1 。这是通过将每个分量除以其大小来完成的。
var a = Vector2(2, 4)
var m = sqrt(a.x*a.x + a.y*a.y) # get magnitude "m" using the Pythagorean theorem
a.x /= m
a.y /= m
a = a.normalized() #功能同上
因为归一化需要除以向量的长度,所以不能对长度为“0”的向量进行归一化。试图这样做会导致错误。
反射
单位向量的一种常见用法是表示法线 。法向量是垂直于曲面的单位向量,定义了曲面的方向。它们通常用于照明、碰撞和涉及表面的其他操作。 假设我们有一个移动的球,我们想从墙上或其他物体上弹回来:
因为这是一个水平曲面,所以曲面法线的值为 (0, -1) 。当球碰撞时,我们取它的剩余运动(当它撞到表面时剩余的量),用法线反射它。在Godot中, Vector2 类有一个 bounce() 方法来处理这个问题。上图有一个使用 KinematicBody2D 的GDScript示例:
var collision = move_and_collide(velocity * delta)
if collision:
var reflect = collision.remainder.bounce(collision.normal)
velocity = velocity.bounce(collision.normal)
move_and_collide(reflect)
点乘
点乘是向量数学中最重要的概念之一,但经常被误解。点乘是对两个向量的操作,它返回一个 标量。与同时包含大小和方向的向量不同,标量值只有大小。
var c = a.dot(b)
var d = b.dot(a) # 与上相同
当与单位向量一起使用时,点积是最有用的,使得第一个公式减少到仅有 cosθ。这意味着我们可以使用点积来告诉我们关于两个向量之间的角度的一些信息:
当使用单位向量(normalized()),结果总是会在 -1 (180°) 和 1 (0°) 之间。
未抄完,待续。