字幕表 動画を再生する
-
- 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!