- This article is about the vector used in algebra. For the type of graphics, see Vector Graphics.
- For more information, see Euclidean vector on Wikipedia.
Vectors are geometric objects with a direction and a magnitude. They are often used to represent physical quantities such as displacement, velocity, force, etc. This article will explain how to use vectors within Scratch.
Definition
A vector is essentially a list of numbers. Each "list item" is called a component. Vectors can have any number of components but 2 is common. A vector that has 2 components could be described as 2-dimensional (2D). This article mostly focuses on 2D vectors for their simplicity and relevance to Scratch (which has a 2D screen).
Vectors can also be represented by the movement from one point to another. They can be displayed as such with an arrow from one point to another.
Notation
The following notation will be used in this article:
- is a vector, with vectors being denoted in bold.
- is the vector with components and .
- and are the first and second components of respectively.
- is a dot product.
- is a cross product.
- is the unit vector .
- is the length of .
Scratch Representation
In Scratch, vectors are often represented with variables. For example, a 2D position of could be created like this:
set [position.x v] to [3] set [position.y v] to [4]
Alternatively a list could be used:
delete all of [position v] add [3] to [position v] add [4] to [position v]
Variables have advantages of readability and performance.
Vector Operations
A lot of the standard operations of natural numbers can be performed on vectors.
Addition
Vector addition consists of simply adding the respective components of two vectors: . This can be represented geometrically by placing a vector at the tip of the other's.
set [a.x v] to [1] set [a.y v] to [2] set [b.x v] to [3] set [b.y v] to [4] set [result.x v] to ((a.x) + (b.x)) // = 4 set [result.y v] to ((a.y) + (b.y)) // = 6
Subtraction
Subtraction can be derived from addition, and only requires subtracting the vectors' respective components:
set [result.x v] to ((a.x) - (b.x)) set [result.y v] to ((a.y) - (b.y))
Multiplication
Vector multiplication (known as scalar multiplication) will be defined only between a scalar (a real number) and a vector, where each of the components is multiplied by the scalar. The same holds for division, with each of the components being divided by the scalar:
set [result.x v] to ((a.x) * (b.x)) set [result.y v] to ((a.y) * (b.y))
Division
A vector can be divided by a scalar, but a scalar cannot be divided by a vector:
set [result.x v] to ((a.x) / (value)) set [result.y v] to ((a.y) / (value))
Magnitude
The magnitude of a vector is its length, and can be calculated using the Pythagorean theorem:
set [magnitude v] to ([sqrt v] of (((a.x) * (a.x)) + ((a.y) * (a.y))))
Direction
The direction of an n-dimensional vector is defined by (n-1) angles; for a 2D vector, only one angle is necessary to calculate its direction, which can be calculated using right-angle trigonometry: (where is the angle).
In Scratch, a 2D vector can be composed from an angle and magnitude like this:
set [a.x v] to (([cos v] of (angle)) * (magnitude)) set [a.y v] to (([sin v] of (angle)) * (magnitude))
To go the opposite direction and find the angle of a 2D vector, many programming languages implement a function called atan2 (2-argument arctangent). In Scratch, it can be implemented like this:
set [angle v] to (([atan v] of ((a.y) / ((a.x) + (0)))) + ((180) * <(a.x) < [0]>))
Normalization
One common quantity we need is the unit vector, which is a vector in the same direction as another, but of unit length. A vector's corresponding unit vector can be calculated by dividing the vector by its length: .
set [magnitude v] to ([sqrt v] of (((a.x) * (a.x)) + ((a.y) * (a.y)))) set [a.x v] to ((a.x) / (magnitude)) set [a.y v] to ((a.y) / (magnitude))
Dot Product and Cross Product
The dot product and cross product are the two main methods of multiplying two vectors together:
- The dot product of two vectors produces a scalar, which can be calculated with two different equations:
- .
- , with being the angle between the two vectors.
- The cross product: of two vectors is only defined in 3-dimensional space[note 1] and produces a vector. The cross product is non-commutative, meaning that .
Let a × b = c.
- The Three-Dimensional cross-product is defined by these two equations:
- , where is the angle between the two vectors and is the unit vector perpendicular two the vectors and .
- The individual components of are defined by these equations:
Note:
- ↑ There exists a seven-dimensional cross product, although it is rarely used in Scratch projects.
Rotation
A vector can be rotated around an axis. In 2D it looks like this:
set [a.x v] to (((a.x) * ([cos v] of (angle))) - ((a.y) * ([sin v] of (angle)))) set [a.y v] to (((a.x) * ([sin v] of (angle))) + ((a.y) * ([cos v] of (angle))))
3D rendering projects in Scratch often chain together multiple rotations around different axes.
A vector rotation in 3D around a vector axis can be efficiently implemented with Rodrigues' rotation formula.
Gravity Example
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)
Finally, we can create an effect of gravity by also changing the velocity by some vector:
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)