From Test-Scratch-Wiki

Revision as of 12:03, 9 April 2018 by HY2009 (talk | contribs)

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]

The direction of a n-dimensional vector is defined by (n-1) angles; for a 2D vector that means just one angle defined by atan2(a.y, a.x).

One common quantity we need is the unit vector, which is a vector in the same direction as another, but of unit length. It can be calculated by dividing each component by the length of the vector: v! = (v.x/|v|, v.y/|v|).

The dot product and cross product are the two main methods of multiplying two vectors.

  • The dot product: a • b of two vectors is a scalar defined by two equations:
    • a • b = (a.x * b.x) + (a.y * b.y). To generalize, the dot product is the sum of the products of the respective components of two vectors.
    • |a|*|b|*cos(theta). theta is the angle between the two vectors.
  • The cross product: a × b of two vectors is only defined in 3 or 7 dimensional space and produces a vector. The cross product is non-commutative, meaning that a × b ≠ b × a.

Let a × b = c.

    • The Three-Dimensional cross-product is defined by these two equations:
      • c = |a|*|b|*sin(theta)*n. theta is the angle between the two vectors and n is the unit vector perpendicular two the vectors a and b.
      • The individual components of c are defined by these equations.
        • 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)
    • The Seven-Dimensional cross-product defined by these two equations:
      • The individual components of c are defined by these equations.
        • 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: Normally, this unit vector is represented with a hat (e.g. â), not an exclamation point, but this is hard to typeset in Wiki syntax.

Scratch Representation

To represent a vector in Scratch, we use a pair of variables, normally called <name>.x and <name>.y. We can then perform addition, subtraction, multiplication, and division on each of those variables independently.

Create a pair of variables position.x and position.y, and write a script to make a sprite continually go to the coordinates given by the position vector. Now, if you set those variable watchers to sliders, you can change the position with sliders.

when gf clicked
forever
 set x to (position.x)
 set y to (position.y)

For something more interesting, create another variable pair called "velocity" (i.e. create velocity.x and velocity.y). Add a new script which changes the respective components of the position vector by the components of the velocity vector. Now, by changing the value of velocity, you should have a much smoother motion.

when gf clicked
forever
 change [position.x v] by (velocity.x)
 change [position.y v] by (velocity.y)
 set x to (position.x)
 set y to (position.y)

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

when gf clicked
set [position.x v] to (0)
set [position.y v] to (0)
set [velocity.x v] to (10)
set [velocity.y v] to (10)
forever
 change [velocity.y v] by (-1)
 change [position.x v] by (velocity.x)
 change [position.y v] by (velocity.y)
 set x to (position.x)
 set y to (position.y)

常用:弹跳

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

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