This is the seventh day of my participation in the August More text Challenge. For details, see:August is more challenging

WebGL Lesson 21: A Non-mathematical Approach to Matrix Multiplication (for those who don't want to do mathCopy the code

primers

# Each equation reduces book sales by half. - hawkingCopy the code

For the last couple of lectures, we’ve had to use these rigorous mathematical derivations to express matrices and matrix multiplication.

If you don’t like math, you won’t be able to watch it, so what if you want to learn WebGL without having to learn the boring formulas?

Think of the matrix as a function

A vector, multiplied left by a matrix, becomes another vector. This form is very similar to our function, so let’s just think about the matrix that way.

Such as:

Function stretch (input vector) {return stretch matrix * input vector; }Copy the code

Does the pseudocode above clearly represent this concept:

Whatever vector you pass in, you're going to get a stretched vector.

Let’s define another rotation function:

Function rotation (input vector) {return rotation matrix * input vector; }Copy the code

So the rotation function above says:

Whatever vector you pass in, you're going to get a rotated vector.

A vector goes through multiple matrix functions

What if we have a demand, a vector, and we stretch it and then we rotate it.

If you are not familiar with the matrix mathematical expression of small partners, certainly muddled.

But according to the matrix function understanding method, then it is very simple:

var A; // An initial input vector A = stretch function (A); A = the rotation function (A);Copy the code

After the above two function calls, we will get a new vector that is first stretched and then rotated.

Multiple matrix merging

Let’s take a closer look at the two codes above and combine them:

A’ = rotation matrix * (stretch matrix * A)

A transpose is equal to the rotation matrix times the stretch matrix times A

A transpose is equal to stretching and then rotating the matrix times A

In other words:

Stretch and then rotate matrix = rotation matrix * stretch matrix

Based on the above, we can define the following code:

Function stretch and rotate function (input vector){return stretch and rotate matrix * input vector; }Copy the code

In other words:

If you have a vector, and you want to flip it over, flip it over, and mess with a bunch of matrices, you can:

You combine these matrices, you throw this vector into this matrix, and you get the vector that you want.

Comprehensive example

There is A vector A (xy)\left(\begin{array}{cc} x\\ y\end{array}\right)(xy)

We want to stretch it first, so x becomes a, y becomes b;

And then rotate it by alpha radians.

Please write a function that can do this.

A = [x,y]; }}}}}}}}}}}}Copy the code
Let’s solve for the combination of matrices

Let’s take the stretched matrix out:


[ a 0 0 b ] \begin{bmatrix} a & 0 \\ 0 & b \end{bmatrix}

We then take out the rotation matrix:


[ c o s ( Alpha. ) s i n ( Alpha. ) s i n ( Alpha. ) c o s ( Alpha. ) ] \ begin {bmatrix} cos (alpha) & – sin (alpha) \ \ sin (alpha) & cosine (alpha) \ end {bmatrix}

Since it is stretched first and then rotated, the combined matrix should be:

[cos (alpha) – sin (alpha) sin (alpha) cos (alpha)] \ begin {bmatrix} cos (alpha) & – sin (alpha) \ \ sin (alpha) & cosine (alpha) \ end {bmatrix} [cos (alpha) sin (alpha) – sin (alpha) cos (alpha)] * [a00b]\begin{bmatrix} a & 0 \\ 0 & b \end{bmatrix}[a00b]

If you’re interested in multiplying these two matrices, you can actually do it by hand, or if you’re proficient in matrix multiplication, you can actually do it in your head:

[cos (alpha) – sin (alpha) sin (alpha) cos (alpha)] \ begin {bmatrix} cos (alpha) & – sin (alpha) \ \ sin (alpha) & cosine (alpha) \ end {bmatrix} [cos (alpha) sin (alpha) – sin (alpha) cos (alpha)] * \ [a00b] begin {bmatrix} \ \ \ & 0 0 & b end {bmatrix} [a00b] = [a ∗ cos (alpha) – b ∗ sin (alpha) a ∗ sin (alpha) ∗ b cos (alpha)] \ begin {bmatrix} a * cos (alpha) & – b * sin (alpha) \ \ a * sin (alpha) & b * cos (alpha) \ end {bmatrix} [a ∗ cos (alpha) a ∗ sin (alpha) – b ∗ sin (alpha) ∗ b cos (alpha)]

So the final algorithm is:

[a ∗ cos (alpha) – b ∗ sin (alpha) a ∗ sin (alpha) ∗ b cos (alpha)] \ begin {bmatrix} a * cos (alpha) & – b * sin (alpha) \ \ a * sin (alpha) & b * cos (alpha) \ end {bmatrix} [a ∗ cos (alpha) a ∗ sin (alpha) – b ∗ sin (alpha) ∗ b cos (alpha)] * (xy) \ left (\ begin {array} {cc} x \ {array} \ \ \ y end right) (x, y)

Let’s do the matrix times the vector 1, 2

A matrix times a vector is a linear combination of the vectors, and a linear combination of the vectors includes:

  • The vector number by
  • Add vectors

Two operations

Let’s first implement the function of vector multiplication:

/ / A = (x, y) / / return/nx, ny function vector number by (A, n) {return [A [0] * n, A n] [1] *; }Copy the code

Then implement vector addition:

/ / A = (x, y) / / B = [w, z] / / return [x + w, y + z] function vector sum (A, B) {return [[0], A [0] + B [1]] A [1] + B; }Copy the code

We know that a matrix is just a bunch of vectors lined up horizontally. We can give a matrix as an array of vectors, for example:

// A = [x, y]; // B = [w, z]; Var matrix = [A, B];Copy the code

Well, we can give a function of a matrix times a vector:

// Vector 1 = [a, b]; // Vector 2 = [c, d]; // D = [vector 1, vector 2]; // A = [x, y] function (D, A){var res0 = vector (D[0], A[0]); Var res1 = vector number times (D[1], A[1]); Return vector sum (res0, res1); }Copy the code
Finally, the function of stretching and then rotating is given:
// A is A vector // The final result is that A is stretched first, and the stretching coefficient is A b. // Then rotate the alpha radian again. Function (a, b, alpha, a) {var D = [[a* math.cos (alpha),a* math.sin (alpha)], [-b* math.sin (alpha),a* math.sin (alpha)], b*Math.cos(alpha)] ]; Return matrix times the vector (D, A); }Copy the code

If you don’t mind the name of the Chinese function, you can change it by yourself. However, the Chinese function name does run directly. Here is an example of the overall code:

Function (A, n) {return [A[0]*n, A[1]*n]; {} function vector sum (A, B) return [[0], A [0] + B [1]] A [1] + B; } var res0 = vector (D[0], A[0]);} var res0 = vector (D[0], A[0]); Var res1 = vector number times (D[1], A[1]); Return vector sum (res0, res1); {var D = [[a* math.cos (alpha),a* math.sin (alpha)], [-b* math.sin (alpha)], [-b* math.sin (alpha), b*Math.cos(alpha)] ]; Return matrix times the vector (D, A); } var A = [1,1]; A = stretch and then rotate (1,1, 3.14/2, A); // Do not stretch, then rotate about 90°. // The result is [-0.9992033562211013, 1.0007960096425679] // approximately equal to [-1, 1]. A = stretch and then rotate (2,3, 0, A); // The result is [-1.9984067124422027, 3.0023880289277036]. // The result is [-1.9984067124422027, 3.0023880289277036]. // The result is [-1.9984067124422027, 3.0023880289277036]. // restore to original [1,1] // result is [1,1]Copy the code

conclusion

This lesson is about a concept:

You think of matrices as functions, and you can merge them.

The combined matrix, the operation with the vector, can get the final vector in one go.




At the end of the text, questions are answeredCopy the code

Little Ya ya said: I don’t want to remember the specific mathematical expression later, I just copy the function and use the function directly.

  • A: That’s the purpose of this class!