字幕表 動画を再生する 英語字幕をプリント - I remember January 2019. Do you remember January 2019? Oh, it was a simpler time. Something happened that month. A video came out on the Internet. This video was called, The most unexpected answer, I'm looking it up, The most unexpected answer to a counting puzzle. And this video was from one of my favorite YouTube channels, 3Blue1Brown, where I learn a lot of wonderful math stuff and I get a lot of inspiration for stuff that I do. And what this video was about is it was about these two blocks. There was a small block, and a big block. And these blocks, they moved around, they bounced into each other, they clacked. It was like, the most beautiful clacking sound I've ever heard. And then they bounced into a wall, and after awhile, just count up how many times they're bouncing into each other, and this weird thing happens, this number appears, this number which is the digits of pi appears based on how many times they're clacking into each other, which is crazy. Now, if you want to know why that occurs, you should go and watch the 3Blue1Brown video series, and even towards the end of that three part series, 3Blue1Brown makes a connection to optics, and there's so much beauty and wonder in there. This is not a new concept, you can find some other resources. There's a wonderful paper from 2003, I'm looking up the title of it now, by G. Galperin called Playing Pool With Pi, The Number Pi from a Billiard Point of View. There's a Numberphile video, and I'll also link to some other resources where you can read about this particular phenomenon and why it occurs in this video subscription. But that's what not I do on this channel. What I do on this channel is I code stuff. So I am going to attempt in this coding challenge to make my own version of 3Blue1Brown's collision clacking magic wonderful thing, and we're going to see like, can I really make this happen, just in the browser and JavaScript, and can I actually write some code that's accurate enough to get the digits of pi? And where does this all break down, and what happens? So, let's code. (whistle blows) Now, to celebrate Pi Day, I'm going to do something a little bit different. I'm going to just start with a little bit of boilerplate code. I kind of use the same stuff in so many of my examples, maybe I can save you five minutes here of retyping this part out. So what I'm starting with is just a very basic object-oriented system. I have a class called Block, and each Block has an x and y, that's where it is in the canvas, and it has a width, it's a square, so the width and the height are the same. And then when I want to draw it, I just draw it as an image, and I've loaded one of my coding train characters. The square character from the coding train. I also have in here a little clack sound loaded that I may or may not use, and then, I have created just two blocks, block1 appears at 100 with a size of 20, block2 appears at 200 with a size of 150, and then I am showing both those blocks. Alright, so what do I need to do? What I want to first do is give these blocks a velocity. So let me go into the Block class and add a velocity, I'm going to call it v. And then I am also going to write a function called update where I will say this.x += v. So the idea here is it has a velocity, and x changes by that velocity. Then, I'll go back to the sketch, and let me give them a velocity, like the block1 is going to have a velocity of zero, and block2 will have a velocity of negative one, and then I should be able to say also here, I can just call update for both of them. Update, update. V is not defined, did I really forget the this dot, already, so already in this challenge? I think that's what I did, I totally forgot this dot. Oh, this dot this dot. So now what I need to do is I need to figure out, how do I check if the two blocks have knocked into each other? Okay, the way that I would do that, let's write a function, I like to do everything in the class when possible. I'm going to write a function called collide, and I'm checking if I'm colliding with another block, call it other. So I'm checking if this block is colliding with some other arbitrary block. So how do I know? If this is block1 with an x and a width, and this is block2, with an x and a width, I know that they are not intersecting if the left side of block2 is greater than the right side of block1, or if it was on the other side, right? If the left side of block1 was greater than the right side of block2. Otherwise, they must be intersecting each other. And I know this is a really simple situation, I don't need to check y's and heights, because they're only moving along this one-dimensional horizontal space. By the way, the math is going to be a key concept here, and where I'm getting to that, if you know, you're like, why not the math? Talk about the math! So now I can say, I can look and basically say, like, if this.x + w, that's the right-hand side, is greater than other.x, other.x, right? Oh no, is less than, right? Or, if this.x is greater than the other.x + other.w, and this has to be a this dot, alright? So now, I'm going to say, println, oh no, print, not collide, not collide, otherwise, print collide. Let's see if I got this right. So it's moving, it's moving, oh, I got to call this function, that would be nice. So I'm going to say block1, 1.collide block2. So I'm adding that in, and it's moving, not collide, not collide, not collide, not collide, not collide, not collide, it's going to collide. It's colliding, it's colliding, it's colliding! Eventually, it's going to get to the other side, go to the other side, get to the other side, not colliding anymore. Okay, my algorithm was correct. So, really if I want that, I want that to just return true or false. So what I'm going to do is, I'm actually going to say, I'm just going to, I could write return, write return false here, but another way I could do this is just say return not, not this expression. This is a test to see if those two blocks are colliding with each other. Oof, alright. If block1 collides with block2, now what I want to say is block1.bounce block2. Alright, I want them to bounce off of each other. So certainly at some point we're going to have to deal with the fact that there's a wall here. But right now I'm just looking at these two, and what I want to do is I want to calculate the new velocities from perfectly elastic collision. So this has a velocity, this presumably also has a velocity, maybe it's moving that way, maybe it's that way, maybe it's at rest. And, in an elastic collision, there's no friction, there's nothing else here in this environment. They're not like squishy things, no momentum, no energy, nothing is lost. So I need the formula for an elastic collision. Luckily, I have that open right over here, and then you can see this is a formula that's following both the conversation of momentum and the conservation of kinetic energy. So with both of these formulas from physics we can then get the new velocity, right? U here is the old velocity, and v is the new velocity. So the new velocity is a function of, the both object's mass, and their previous velocity. Let's first add the idea of mass. So I'm going to go in here, and I'm going to add the idea of mass. And first I'm just going to say, hey, the mass is one, so let's not worry about mass right now. By the way, what happens if the mass is one? Think about this. If they're equal mass. If they're both equal mass, and this one is stationary, and this one's moving, and they clack, right? All of the momentum and energy is transferred, this one stops, this one moves. But that's not what's going to happen when the masses of each are different, so that's when it's going to get really interesting, okay. So now we want a function called bounce, and I'm also going to say other. And it would be really nice if I could just have that formula right over there for me to refer to. Alright, so I took a screenshot of the formula, so I've got it over there to refer to, and I just need to implement it here in this bounce function. So, one is this, two is other. So I'm writing it, I'm not referring to my blocks as block1 and block2, I'm referring it to within the object as this and other. So what I want to do is say this.v, but I don't want to start messing with v, because the old value of v is part of the formula. So let's do this, const.v. Actually, you know what? Let's do, let's do, sorry, let newV = this.m-other.m, divided by what? Let's make a variable called sum of M, which is this.m + other.m. So this is divided by sum of M, and then, times this.v, right? So that's this side, and then, I mean, I could do this in one line, but I'm running out of space here. So then += 2 * other.m, divided by sumM * other.v. So I think what might make sense here is the thing is I don't want to update this object's velocity. I guess I could do both of them. I'll just do both of them in this function. I was thinking I could return it, and then 'cause it's the same formula both ways, I'd rather not duplicate my code. Let's try it this way. I'm going to return newV. You can see how this is the same formula twice, it's just written in reverse order for v2, but if I change the two there, and change all the twos to ones, we'll get the same thing. So I should be able to say, if I go back into sketch.js, and I say, I'm going to say v1 = block1.bounce block2. I'm going to say v2 = block2.bounce b1, block, block1. And then I should say, I'm going to update their velocities. This I don't know if I love, but this will work. So let's see what we got here. C'mon, clickety clack, go, bounce that thing!