[BELL DING]
Hello.
Welcome to another video in Nature
Of Code, Chapter 1, Vectors series.
I really thought that in this video,
I was going to start making this example.
I almost have arrived there, where this mover object is
accelerating towards the mouse.
But there's a particular math function
that I'm going to need for this example,
that I want to cover in a separate video.
And that's the Normalize function.
I want to look at how I deal with
and calculate the magnitude of the vector, how
I normalize a vector.
What does that even mean?
And the way that I'm going to do this
is look at creating a vector between the mouse
and the center of the canvas, itself.
The scenario I want to look at is as follows.
I have a canvas, and I have some mover on the canvas,
a particle somewhere.
Let's just position it in the center.
Let's say this is 600 by 400.
It's not exactly drawn to scale, but close enough.
So this is 300 comma 200.
Then I have the mouse.
I'm moving my mouse around somewhere.
And let's say I have the mouse over here.
I'm going to try to draw a mouse arrow.
And we'll call this location 580 comma 20.
What I'm looking to do is figure out
how do I calculate, if I know this position
and this position, a vector that points from one to the other.
If I want this particular particle
to accelerate towards the mouse, how
do I calculate this particular vector?
Call it V. Well, when I say calculate the vector, what
I'm really looking for is the x component and the y component.
So v dot x equals what?
580 minus 300.
So 580 minus 300, that's 280.
v dot y equals 200 minus 20.
This length is 180.
So this vector is 280 comma 180.
What mathematical operation did I just do, here?
I have two vectors, really.
I have this vector, which I'll call position.
And I have this vector, which I'll call mouse.
What I did is I said mouse minus position
gives me v. v equals mouse minus position.
Let's confirm that this really works, the subtract operation,
by diagramming this.
So if I take this mouse vector that's
pointing from 0 to this location, 580 comma 200,
and I draw that down here, this is not exactly right.
But I just sort of duplicate this, here.
If I were to add, if I were to say plus position,
I'd put these vectors end to end.
So we'd take this vector and put it over here.
I'm about to go out of your range of view,
so I'll just draw a little bit shorter.
But this is the idea.
Mouse plus position would give me this vector.
Mouse plus position.
But I want to say mouse minus position.
So that's taking this position vector
and pointing it in the opposite direction.
This is minus position.
So mouse minus position is this vector, v, right here.
And you can see that matches up with that.
So this example is drawing random vectors
that emanate from the center.
Let's try that math operation.
I'm going to actually get rid of all this.
And I'm going to say position equals
createVector, the center of 200, 200.
Mouse equals createVector, mouseX, mouseY.
And then v is--
to do this subtraction, mouse minus position
and store it in a new vector, I need a static function!
That's what the previous video is about.
So I can say p5 dot Vector dot subtract mouse minus position.
And actually, let me put the translate back,
because I want to draw everything
relative to the center.
Oh, look at that.
I still have the funny background thing,
which I'll keep.
So no matter where I move the mouse,
I now have a vector that points from the center to where
the mouse is.
Now, certainly, this visualization
could have been created just by calling the line function
and saying line 200, 200, mouseX, mouseY.
But the reason why I'm doing it this way,
through vector subtraction, is to show you
about the normalize function and what kind of power that
unlocks.
Let's say that I have a collection of vectors.
Let me draw five of them, all random directions, all varying
lengths.
Those are my five vectors.
The process of normalization, which
is executed with the normalize function in P5.js
is to take any vector of any length and any direction
and make it into a unit vector.
A unit vector is one where the magnitude of the length is 1.
So let's just establish that this is approximately length 1
in terms of this arbitrary, two dimensional space I'm
working with.
So this vector normalized would be this vector.
This vector normalized would be this vector.
This vector is less than 1, so normalizing it would actually
be to grow it.
It would be this vector.
This vector would be this vector,
and this vector would be this vector.
Now, of course, I would draw these exactly right.
But this is the idea.
All of these are normalized versions of these.
And you could think of the term normalized
as making all these vectors into a normal vector, normal being,
well, a normal vector is length 1.
Otherwise, it's some wacky, crazy, insane vector
with a much longer length.
It's basically having a standard.
By the way, in vector notation, a vector
is typically written like vector v with an arrow on top.
The unit vector is often written as vector v
with the hat or carrot on top.
So this would be a unit vector v or any given vector
v. So if I come back to this example, here,
one of the things we could look at is
I could say v dot normalize.
What does that do?
Well, it makes the vector length 1,
so I could just keep zooming into this.
I'm drawing something of pixel length 1.
So how does the math for normalize work?
Luckily, for us, we can just call normalize in P5.
But this is a moment for us to take a little time
to look at the math for that.
Well, before we can look at the math for normalize,
we actually should look for the math
at another function called mag.
And mag is a function that returns
the magnitude of a vector.
So it returns the scale or length of any given vector,
that magnitude itself.
So one thing that I could do here
that could demonstrate this is let me take the background
and draw it in Draw.
Run this again, and I guess I will make this much brighter.
So now, I've just got this line pointing to the mouse,
and I'm going to ask for the magnitude.
So that is now getting the magnitude of that.
And actually, let's just console log it.
So you can see, this console log,
down here, is giving me the magnitude of the vector itself.
As I move the mouse closer to the center,
you can see it's always a positive number, because it's
the length of it, no matter what direction it's pointing in.
I could try something interesting,
like I could say, oh, let's make the background color associated
with the magnitude.
So now, you can see the closer the mouse gets to the center,
the brighter the background is.
It's sort of an interesting interaction
that you could play with.
And the reason why this magnitude value is so important
is it plays a fundamental role in how a vector is normalized.
Let's say I take this vector, and this is the magnitude, m,
and this is the x component and the y component.
Well, another way I could draw this diagram
is like this, a right triangle with a, b, and c.
And if you've ever seen this kind of diagramming
in a geometry context, you might have
seen it paired with something called the Pythagorean theorem.
The Pythagorean theorem states that a squared plus b squared
equals c squared, or c equals the square root of a squared
plus b squared.
And in fact, that is exactly how the magnitude is calculated.
So when the mag function is called on a vector, v dot mag,
it takes the square root of the x component squared
plus the y component squared, and that gives you
that magnitude.
Now that I understand how magnitude is calculated,
I'm ready to look at how normalization works.
Let's use the 3, 4, 5 triangle as our starting point.
So once I have a vector, its components are 4 and 3.
We know that the magnitude now equals the square root of 4
squared plus 3 squared, which is 16 plus 9, which is 25,
the square root of which is 5.
So the magnitude is 5.
You can see how this math for calculating the magnitude, now,
works out.
If I wanted to normalize this vector,
that means I want to shrink this length, which is 5, down to 1.
So it turns out, if I'm taking a vector
and normalizing its length down to 1 or up to 1, 5 divided by 5
is 1.
I can actually just take the x and y components
and divide by the magnitude.
So this length, right here, is actually 3/5.
And this length, right here, is actually 4/5.
And that's how you normalize a vector, by dividing it
by its magnitude.
So removing this background little digression,
I can now actually normalize v by saying
v dot divide, div for divide, a vector by its magnitude.
So if I do that, wait a second.
Well, there it is.
You can see, no matter where I put the mouse,
I have this nice vector of length 1.
But maybe what I should do is then
scale it up by something like 50, multiplying it.
And look at this.
So now, I have this multi-step process
to make a vector that points in a given direction with a fixed
length.
I have some vector that I've calculated, call it v.
And the first thing I do is I call v dot mag, which
gives me the magnitude.
Maybe it's 100.
So the length is 100.
Then what I want to do is normalize the vector.
I want the vector to be that same vector, but of length 1.
So I can say v dot divide by that magnitude or 100.
That takes this vector and shrinks it down to here.
Then I want to scale it up by some amount, like 50.
And that will then scale it back up to a higher length of 50.
So this is my multi-step process,
but this is with all of this math.
And in fact, instead of calculating the magnitude
and dividing by the magnitude, I can just, instead, call--
it's such a common operation--
v dot normalize.
So v dot normalize is the act of taking any vector
and shrinking it to length 1.
I did a terrible job of drawing these in the same direction,
but hopefully, you get the idea.
So now, I can simplify this by commenting these out and just
changing this to v dot normalize.
And we've got the same exact result. But guess what?
v dot normalize, v dot multiply times 50,
is also such a common operation--
like I want this vector in this direction,
but I just want it to be this magnitude--
that, in fact, I can even take these
and just call v dot setMag 50.
So this function, v dot set the magnitude of a vector,
is the process of normalizing it down to length 1
and then scaling it to a particular magnitude,
in this case, arbitrarily, 50.
And the process of normalizing is calculating the magnitude
and dividing by that magnitude.
And we should see this is the same result.
Incidentally, it's worth pointing out
that I could actually go and confirm this
by looking in the P5 source code, itself.
So this is the source code for the P5 vector object, itself.
And there's a normalize function,
which what does it do?
It calculates the magnitude.
And as long as the magnitude isn't 0--
because you can't divide by 0--
then it multiplies by 1 divided by length, which is
the same as dividing by length.
So that is the normalize function.
I could even look at the setMagnitude function
and see that it's normalize the vector
and then multiply it by some quantity, n.
In fact, you can see here that's something that I'm not doing
is chaining.
So a lot of these math operations on vectors
can be chained, meaning I can say normalize, multiply.
And by that, I mean these two operations, v dot normalize,
v dot multiply could be written as v Dot normalize dot multiply
50.
So once again, we now see there are
so many different ways to do the same exact thing.
But hopefully, this is giving you
a better picture of what vector math operations do,
how they work, and how you might choose between static functions
versus instance functions, and how
you might manipulate vectors by using
these mathematical operations.
So I think this truly is the penultimate video
in the chapter on vectors, because we're now
ready to take this idea of calculating a vector that
points to the mouse and apply it as an acceleration to an object
and see what happens.
So that's coming in the next video!
See you there.
[MUSIC PLAYING]