字幕列表 影片播放 列印英文字幕 [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]
B2 中高級 1.5 A單位向量(規範化)--代碼的性質 (1.5 A Unit Vector (Normalize) - The Nature of Code) 2 0 林宜悉 發佈於 2021 年 01 月 14 日 更多分享 分享 收藏 回報 影片單字