[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]