From Test-Scratch-Wiki
- See also: Vector Graphics
Vectors are ordered sets of numbers, used in algebra to represent many different things. Most of the time, they are used to represent various physical quantities in physics simulations or games. This article will explain how to use vectors with Scratch to produce interesting effects.
Contents
What Vectors Are
Vectors are like lists, except you cannot add or remove items. Their "items" (components) are numbers. For this article, we will only consider 2-dimensional vectors with 2 components, however, vectors can have any number of dimensions or components, even 4 dimensions. For example, raytracing requires 3-dimensional vectors. Vectors by definition are quantities consisting of one magnitude and one direction. They can be graphically defined with an arrow.
2D vectors can be represented as points on the Cartesian plane be graphing their X component on the X axis and Y component on the Y axis. So we can represent the positions of sprites as vectors.
Vectors are used in graphics to represent many things such as positions, velocities, forces, etc. . Using vector math, you can simulate complex phenomena such as collisions.
Notation
Due to the limitation of mathematical notation, the following notations are used throughout:
- (x, y) or <x, y> is the vector with x and y.
- a.x and a.y are the x and y components respectively.
- a +,-,*,/ b are the respective operations with a and b as operands.
- a • b is a dot product.
- a × b is a cross product.
- a! is the unit vector a.
- |a| is the length of a.
Vector Operations
A lot of the standard operations of natural numbers can be performed on vectors. Vector addition consists of simply adding the respective components of two vectors: (1, 2) + (3, 4) = (4, 6). Imagine drawing the second vector at the tip of the first.
Subtraction can be derived from addition: just subtract the respective components: (5, 4) - (3, 2) = (2, 2)
For our purposes, vector multiplication is between a scalar and a vector, where the scalar is multiplied by each of the components —the same holds for division, with the reciprocal of the scalar operand: 5 * (2, 3) = (10, 6)
A vector can be divided by a scalar but a scalar cannot be divided by a vector:
- (15, 25) / 5 = (3, 5)
- 4 / (16, 24) = NaN
The magnitude of a vector can be calculated using the Pythagorean theorem: |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)
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)
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)
A common use: bouncing
A common use of vectors is to simulate a body bouncing off an arbitrarily angled surface. To make a bouncing script, we need to calculate the perpendicular vector to the surface, then project the velocity vector of the body on that to find the component of the vector that is reflected.
To find the perpendicular, we switch the X and Y components, and negate any one. Projection is a bit tougher, and requires the dot product. The dot product (a • b).