From Test-Scratch-Wiki

Template:另见 矢量 是一种既有大小又有方向的量,又称为向量。一般来说,在物理学中称作矢量,例如速度、加速度、力等等就是这样的量。舍弃实际含义,就抽象为数学中的概念──向量。大多数时候,它们被用来表示物理模拟或游戏中的各种物理量。本文将解释如何在Scratch中使用矢量来产生有趣的效果。.

什么是矢量

向量就像列表,除了你不能添加或删除项目。他们的“项目”(组件)是数字。对于本文,我们将只考虑具有2个分量的2维向量,但向量可以具有任意数量的维度或分量,甚至4个维度。例如,光线跟踪需要三维向量。按照定义,矢量是由一个大小和一个方向组成的量。它们可以用箭头图形化地定义。

2D矢量可以表示为笛卡尔平面上的点,其可以绘制其在X轴上的X分量和在Y轴上的Y分量。所以我们可以将精灵的位置表示为矢量。

图形中使用矢量来表示位置,速度,力等许多事物。使用矢量数学,可以模拟复杂的现象,如碰撞。

符号

由于数学符号的规定,整个过程使用以下符号:

  • (x, y)<x, y> 是带有x和y的向量.
  • a.xa.y 分别是x和y分量.
  • a +,-,*,/ b 是a和b作为操作数的相应操作。
  • a • b 是点积.
  • a × b 是叉积.
  • a! 是向量a.
  • |a| 是a的长度.

矢量操作

很多自然数的标准操作都可以在矢量上执行。向量加法包括简单地添加两个向量的相应分量 (1, 2) + (3, 4) = (4, 6). 想象一下在第一个矢量顶端绘制第二个向量.

减法可以从加法导出:只需要减去相应的分量: (5, 4) - (3, 2) = (2, 2)

对于我们的目的,矢量乘法是在标量和矢量之间,其中标量乘以每个分量 - 对于除法,标量操作数的倒数也是相同的: 5 * (2, 3) = (10, 6)

一个向量可以被一个标量分割,但一个标量不能被一个向量分割:

  • (15, 25) / 5 = (3, 5)
  • 4 / (16, 24) = NaN

矢量的大小可以使用毕达哥拉斯定理计算: |a| = √[(a.x)2+(a.y)2]

N维向量的方向由(n-1)个角度定义; 对于二维矢量来说,这意味着只有一个由atan2(ay,ax)定义的角度。

我们需要的一个常见量是单位矢量,它是与另一个方向相同方向的矢量,但单位长度是单位矢量。它可以通过将每个分量除以矢量的长度来计算: v! = (v.x/|v|, v.y/|v|)

点积和叉积是两个向量相乘的两种主要方法。

  • 两个向量乘法:a • b :
    • a • b = (a.x * b.x) + (a.y * b.y). 概括地说,点积是两个向量的各个分量的乘积之和.
    • |a|*|b|*cos(theta). theta 是两个向量之间的角度。
  • 交叉积: a × b两个向量的a×b只在3或7维空间中定义并产生一个向量。交叉积是不可交换的,意味着a×b≠b×a。

a × b = c.

    • 三维交叉乘积由这两个方程定义:
      • c = |a|*|b|*sin(theta)*n. theta 是两个矢量之间的角度,n是垂直矢量a和b的单位矢量。
      • c 的各个分量由这些方程定义。
        • c.x = (a.y * b.z) - (a.z * b.y)
        • c.y = (a.z * b.x) - (a.x * b.z)
        • c.z = (a.x * b.y) - (a.y * b.x)
    • 由这两个方程定义的七维交叉乘积:
      • c的各个分量由这些方程定义:
        • c.x = (a.y * b.z) - (a.z * b.y) + (a.w * b.v) - (a.v * b.w) + (a.u * b.t) - (a.t * b.u)
        • c.y = (a.z * b.x) - (a.x * b.z) + (a.w * b.u) - (a.u * b.w) + (a.v * b.t) - (a.t * b.v)
        • c.z = (a.x * b.y) - (a.y * b.x) + (a.w * b.t) - (a.t * b.w) + (a.u * b.v) - (a.v * b.u)
        • c.w = (a.v * b.x) - (a.x * b.v) + (a.u * b.y) - (a.y * b.u) + (a.t * b.z) - (a.z * b.t)
        • c.v = (a.x * b.w) - (a.w * b.x) + (a.t * b.y) - (a.y * b.t) + (a.z * b.u) - (a.u * b.z)
        • c.u = (a.x * b.t) - (a.t * b.x) + (a.y * b.w) - (a.w * b.y) + (a.v * b.z) - (a.z * b.v)
        • c.t = (a.u * b.x) - (a.x * b.u) + (a.y * b.v) - (a.v * b.y) + (a.z * b.w) - (a.w * b.z)
Warning Note: 通常,这个单位向量用帽子表示(例如â),而不是感叹号,但这很难在Wiki语法中进行排版。

Scratch 中实现

为了在Scratch中表示一个矢量,我们使用了一对变量,通常称为<name>.x and <name>.y.。然后我们可以独立地对每个变量进行加,减,乘和除。

创建一对变量position.x和position.y,并编写一个脚本,使Scratch不断转到由位置向量给出的坐标。如果您将这些变量显示窗设置为滑块,则可以使用滑块更改位置

点击绿旗时
重复无限次 
  x 设为 (position.x)
  y 设为 (position.y)
end

对于更有趣的事情,创建另一个名为“velocity”的变量对(即创建velocity.x和velocity.y)。添加一个新的脚本,用速度矢量的分量改变位置矢量的各个分量。现在,通过改变速度的值,你应该有一个更平滑的运动。

点击绿旗时
重复无限次 
  变量 [position.x v] 改变 (velocity.x)
  变量 [position.y v] 改变 (velocity.y)
  x 设为 (position.x)
  y 设为 (position.y)
end

最后,我们还可以通过改变某个矢量的速度来创建重力效果:

点击绿旗时
变量 [position.x v] 设为 (0)
变量 [position.y v] 设为 (0)
变量 [velocity.x v] 设为 (10)
变量 [velocity.y v] 设为 (10)
重复无限次 
  变量 [velocity.y v] 改变 (-1)
  变量 [position.x v] 改变 (velocity.x)
  变量 [position.y v] 改变 (velocity.y)
  x 设为 (position.x)
  y 设为 (position.y)
end

常用:弹跳

矢量的一个常见用途是模拟一个从任意倾斜的表面反弹的物体。为了制作弹跳脚本,我们需要计算表面的垂直向量,然后将该体的速度向量投影到该面上以找到反射的向量的分量。

为了找到垂线,我们切换X和Y分量,并取消任何一个。投影有点困难,需要点积。点积 (a • b).