♪ I will refactor this later you know ♪
- Hello and welcome to Coding Challenge:
the Chaos Game, part deux (says in French),
electric boogaloo (laughs),
I don't know what I'm talking about.
Thank you to Espen Larsen, @drcircuit on Twitter
for creating the "I Will Refactor This Later" song,
this coding challenge is in honor of that song,
because, guess what...
"Later" is now,
I will refactor this now.
So what I'm going to do in this coding challenge
is expand this idea of the Chaos Game.
Instead of merely creating this Sierpinski Triangle,
I'm going to make a version of this
where there could be more than three points, seed points,
and that, as the points move,
as the newly random point move moves
from point to point to point,
I might move by a different percentage than 50%.
So if you didn't watch the previous coding challenge
where I made this,
you could pause now and go watch that,
or you could just stay here with me right now,
let's be together, let's be friends on the Internet,
programming stuff, okay.
So the first thing that I wanted to refactor this,
I really want to play this song again,
but I'm not going to overdo it,
I'm going to use it sparingly,
otherwise people will get irritated and annoyed
and I'm sure I will hear about it.
The first thing that I wanted to do
is I am going to make a array called seed,
maybe I should call it seed points,
let's just call it points, I don't know,
let's call it points.
And instead of having ax, ay,
what I'm going to do in this array,
let's get rid of this.
First, I just want to recreate this exactly,
I am going to, say I'm going to have three points,
and I'm going to create a new point,
which is a vector,
I'm going to use vector createVector function
to make a new point anywhere randomly in the canvass.
I know I've run a little bit out of space here,
but that's fine.
Come on, a little bit further over,
wow, there's a space for a semicolon.
And then I'm going to say points.push(v), okay.
And then I'm going to have a point called current,
which is also going to be...
A vector, a random vector.
There we go, there we go.
So now what I can do is again,
I have just refactored this
to instead of having separate x, y variables
for all four points, I have an array
that keeps my three seed points
and I have my current point in,
all current points at separate variable
and both of those are p5-vectors.
A vector being an object that can hold an x, y, and z.
But I'm not going to use the z right now,
although, you could do this in 3D, oh, you should,
you should do this in 3D.
I'm not going to.
Alright, so then I'm going to say,
for (let p of points),
and I'm going to say, point(p.x, p.y);
so we should see, there we go.
Those are my first three seed points
and then what I'm going to do here is
random the length.
And this is actually now,
oh, you know what, I don't even need to do this,
guess what, the random function in p5,
I'm going to say like next equal to random function in p5
will give me a random object out of that array.
Now if I want to pick them with a different probability,
I'd have to do something different,
but here, this next is now going to be one of those
three points randomly.
And then all I need to do is say,
stroke, I'm going to still give it this color,
and then I'm going to say,
next.x = lerp, this.
So I'm lerping, but I'm going to lerp between next
and the current.
Oh, and current is the result of that.
So the current is the thing that's moving
and it's really doesn't matter,
but I like to think of it in this order.
Current is moving and I think there's actually
a lerp() vector function,
so I could do this in one line of code.
That's another "refactor this later-now" (laughs).
So there we go,
and then all I need to do
is draw the point,
all I need to do is draw that point...
(keyboard tapping loud)
And here we go, look at this, ta-dah!
Now, one thing I should probably do
is also reset it.
Let's actually, all of this stuff here,
is kind of the process of,
let's right a function of resetting,
like, I want, right now it's like resetting
every time I change the code,
because of the p5 editors configured it
to, like, relaunch the sketch,
but I think what I would prefer to do here
is right my own function called reset(),
this is a nice refactoring.
And I need to empty the array,
and I'm going to say points equals, here.
So this function reset()
will just sort of reseed the environment.
And I could do it whenever I click the mouse,
but just for right now, I'm going to say,
if frameCount modulus, like, 100, equals zero,
then reset().
So what that's going to do is every 100 frames, right,
because modulus of the number 100 will equal zero
any time the frameCount is divisible by 100
with a remainder of zero.
So you can see, over and over again, this is going to,
so, no, I'm, I'm here, I have refactored this.
But now that I have refactored this,
there are so many possibilities,
oh, this is exciting, okay.
So, for example, I could just do this.
No, oh, yeah, look.
Now, interestingly enough, I don't really get
a pattern that's super interesting to look at
with four points.
Kind of accidentally I sometimes am.
And do so what happens if have eight points.
Whoa, this is crazy.
Now, probably what I would want to do,
what might make sense for me to do,
is place these points around a circle,
just, I mean, it's interesting to have them randomly,
but I think I would prefer,
just to sort of figuring out what I want to with this,
to have all those points around a circle, right,
so you can think about it, actually,
this was a way of getting my equal lateral triangle
that I was looking for.
So what if I have eight points and then I get
some kind of like hexagon, octagon, septagon,
whatever the number of sides is,
based on the number of points.
Alright, so what I'm going to do here, actually,
I'm going to have a fixed set of points, right.
So the points are, I'm just going to do once in set-up.
And what I'm going to do is I'm going to use the constant.
Const n equals eight,
I know I could be using constants other place of the code,
and if you want to know more about consts,
I made a video about it
where I got a bunch of pics wrong, but you can watch,
so you might find a different resource for that.
But so, I just, now I'm making n points
and what I'm going to do is say the angle
is TWO_PI divided by, aye, that's a bad idea,
because I don't want to divide by zero.
So, alright, we'll say, um...
Oh, it's, I know what it is,
it's i times TWO_PI divided by n,
that's what it is, right,
because I want to have, I'm looking for,
if n is four, for example, I want zero degrees,
90 degrees, 180 degrees, 270 degrees.
It's probably going to go the other way,
because the screen is flipped, but that's the idea.
So now, what I'm going to do is say,
createVector at...
Some number like, let's just do 200
times cosine of the angle,
oh, you know what, I think there is p5.Vector from
p5.Vector fromAngle,
I think, is a function, angle.
So it's going to make a vector from that angle.
And then I can say V dot, um...
V dot
Multiply 100,
and that's working,
but I need to translate to width divided by two,
height divided by two.
And now we have these points in the center,
of course I also, if I wanted,
I need to do that here, okay.
So there we go, we can see now
I've created eight points around
and let's actually use, um,
let's make that a little,
ooh, why is this down here?
Ooh, oh, there's a weird mistake,
a goofy mistake happening.
Oh, because when I reset, err,
this is kind of, you know what I'm going to do?
The translator's fine, but it's bothering me,
I'm just going to make life easier on myself
and say, add, width divided by two,
hight divided by two,
I'm just going to move that to the center manually
by adding that to the vector, okay.
Now what I want to do is multiply it
by, like, width divided by two, or something.
Okay, great, ha, so now you see,
those are all my points,
we're still playing the Chaos Game.
Now what I want to do is I'm going to have
a variable called percent.
And I also, I just want to make, like, a lot more points
really quickly, so I can just sort of see the pattern.
And what I'm going to do now is,
I am going to try, I'm going to when I lerp,
I'm going to lerp by that percent
and let's try different values.
So let's try, so let's go back to point five
and this is what I get.
Let's try point two-five.
Interesting.
Let's try point one.
Let's try n of four,
point two-five.
(bell rings)
Alright, I'm back.
Nico Monsoon in the chat said,
"Try three, just to see if you didn't break anything."
So I made the point n equals,
I made n equal three,
with the percentage of point five,
and we could see I have the Sierpinski Triangle.
Actually, if you look on the Wikipedia page for Chaos Game,
you'll start to see a bunch of these.
"A point inside a square repeatedly jumps
"half of the distance towards a randomly chosen vertex,
"but the currently chosen vertex cannot be two places
"away from the previously chosen vertex."
so this is interesting, right?
So I could actually start to create
some of these patterns by modifying
how I pick a particular point.
So this one actually would be nice.
Let's do the pentagon one.
"A point inside a pentagon repeatedly jumps
"half of the distance,
"but the currently chosen vertex cannot be the same."
This is going to be an easy one for us to implement.
We just need to get a new random number
that's not the same as the previous one.
So, um, so let's go back here.
Let's first make this five, okay.
So we can see, even with five, a pentagon,
we're kind of getting a somewhat
of an interesting pattern here.
I don't know why I obsess over this sort of stuff,
but I kind of feel, like, let's give this just like
a little bit of alpha
and make the strokeWeight one and do, like,
a thousand points.
So we can just sort of see this pattern more quickly.
Okay, now, what was I doing?
Ah, so what I want to do now is not allow the next point
to be the same as what was previously chosen.
And so there's a variety of ways I could do this,
but actually I could just create a way of,
I could just create a way of ignoring it
if it happens to be the same one.
So let's say, previous,
I'm going to create a variable called previous.
And right here, where I pick previous equals next,
and I'm going to say, as long as next is not equal
to previous, then I could do this stuff.
So now look at this.
There we go, the Chaos Game, pentagon
with one slight modification.
And you know what,
I don't want this to keep resetting,
I just want it to, um...
I want to tell it not to reset,
and I want to go to Share,
Full Screen,
and I'm going to put this in a different window
and we're going to bring this up here
and we're just going to enjoy this.
Now, okay, here we go, we are done, ha,
Chaos Game, thank you very much.
Look at this,
it's so beautiful, and intricate, and amazing.
So I now encourage you, now you really got something,
you can start to make a variety of patterns
and, really, here's the thing,
one thing that you could do that actually
is really, if you could think about,
that I didn't do, if we go up here,
look at this.
This is actually a little, sort of,
animated gif showing you the process
of actually moving the points from one spot to another
and then to re-branching out.
So imagine what you could do if instead of just picking
all the points and layering them,
you actually created a system where you animate
the process of building this pattern.
And you could see, you could see,
maybe you can recreate some of these other patterns
by doing these rules.
This one would be a nice one to create.
You could try different percentages
and see what you make.
So, thank you for watching this second part
of the Chaos Game, I think we are done
with all the chaos game stuff I'm going to do.
If you make your own version of this,
please visit thecodingtrain.com link
that's in this video's description.
There, there are instructions for how to submit
alike to the version of the Chaos Game
that you made yourself.
You can share with me your images or gifs
on Twitter @shiffman or @thecodingtrain,
hashtag...
codingchaosgame,
and I'll see you in the future coding challenge, alright.
I don't know, maybe, I will--
♪ I will refactor this later-- ♪
Wait, wait, wait, wait, wait,
let's refactor this now,
I'm not actually refactor it,
I realized something.
When I was playing with the percentage earlier
and making it lower,
I started to get much noisier images,
and, of course, this is true,
because I'm not going very far.
And so the points are sort of layering
on top of each other and I'm just getting
kind of a cloud of points.
But what if instead of going half way there,
and, um, let's actually, I know I'm being
kind of a lunatic about this stuff,
but let me just make this white.
Instead of going half way there,
what if I go 75% way there.
So actually going further will start to yield
some interesting patterns.
And you can see here now, if is say 15,
look at this.
So this is now 15 points going 75% of the way there.
And by the way, maybe, if I were to make,
oh, that's 90% percent of the way there,
if I were to make some sort of slider
or I varied a number of points,
I could go back to putting these points
all in a random location,
that would be kind of interesting.
Oh, let's do that now, I'm just curious.
So where do I, uh, let's do this.
Let's just really quickly,
I'm just curious to see,
I got to stop, you should...
I shouldn't be doing this,
you should be doing this.
So you could see, ah, okay, I'm not (mumbles),
so anyway, so that's, this is a clue to you
of what you could now make, right,
that I told you to share with me.
You could vary that percentage,
vary the number of points,
vary where the seed point starts,
animate, oh, so many possibilities, okay,
see you later!
(upbeat electronic music)