(rings bell) (blows flute) Hello, and welcome to a 2018 holiday coding challenge, snowflakes! So, I was perusing the
internet last night, and I found this page, I
think my search term was like, Brownian motion snowflake fractal, and I found this page, it's from a website called Code Golf that
has a lot of different coding challenges on it. I think the idea of the
challenge is to write the shortest amount of code
to create this kind of effect. I am not going to attempt that, I'm probably going to write
the longest amount of code to make this kind of effect, but my goal is to try to make a
snowflake pattern like this. Now, if you read over this
webpage, and there's a few diff, this is an example
that was made in Mathematica, which I don't understand at all. But the algorithm that's
described here is, you can, here that it's a Brownian
tree on an integer lattice, that sounds so fancy! The idea is, if you just
think about a number line, or the x-axis of any coordinate system, and I were to start
with a point back here, and I were just to allow that point to, like, randomly move around, do a random walk, so to speak, random walk, and at some point I would
have to tell it to stop. So maybe, maybe what I would do, is I would tell it to stop if
it got to, like, over here. (laughter) The path, maybe this
is the 0, 0 coordinate. If it got to here it should stop. And then I'm going to start another one. And I'm going to let that
one do a random walk. Now, it's going to stop also if it gets to either past here, or if it
touches another previous, I'll call these particles. And this, by the way, is
basically an algorithm called Diffusion Limited Aggregation. And this is actually something that I have done previously
in a coding challenge. I'll pull up that page right here. You can, I'm mostly going to
implement the exact same thing. But you can see you'll get
this branching pattern. So here, the dot, there's one dot that starts at the center and everything kind of
branches out from there. And we could use a
recursive tree structure. There's all sorts of kinds of way we could create this branching pattern. But what's interesting about this, how can we make a snowflake? Well, I don't really know. I'm not, no expert on the
actual science of snowflakes, but if you've looked at
most snowflakes' designs, they are in a hexagonal pattern. We can think of that as a bunch of, like, triangular slices. Slices of a pizza pie right here, right. So if I were to kind of constrain this branching to within this sort of half of this slice, like right here, then what I could do is I could take this, I could reflect it on the other side, which would give it some symmetry, and then rotate it also around six times, and I think, I'm pretty sure,
that's what that is happening in that animation that I
showed in the beginning. So this is what I'm
going to attempt to do. I'm sure, I'm not sure, but I expect there are lots of creative possibilities with color, and improving the algorithm, and size, and rendering that you could do from watching this. So my hope is that we will now be filled with a world of code made snowflakes. But let's start this and see. It's similar to probably also to, like, what you would do to make a
kaleidoscope program I think. So let's start trying to do this. I'm going to do this in Processing, which is a Java based
programming environment. This is, by the way, being
recorded during a fundraiser. You can go to
processingfoundation.org/support to make a donation to the
non-profit Processing. And I will also release
a JavaScript version in p5.js that you can also use to make this thing happen in the browser. Alright, so the first
thing that I want to do is I just want to make a particle. Oh I guess I need to have a class. (laughter) So let's make a class called particle. Do I dare use p-vectors? Let's try to be simple for a little bit here for a second. Let's start without p-vectors and let's just make the particle have an x and a y, and I'm going to say the particle is going to start at some other x and y, so this is a, this is a class from which I'm going to
make particle objects, and this is the class's constructor that is going to receive an x and a y and create the particle there. I probably actually don't, I could've just used a
single vector actually, but that's fine. Let's make a particle class. And then what I'm going to do is I'm going to write a function called, like, update and I'm going to say x equals, so I'm going to do a
really simple random walk, which it's all, I'm going
to make the particle, I'm going to start it this way. I probably want to,
like, start the particle somewhere around here, and then have it randomly
walk in this direction to stay within the slice, but just for simplicity's sake, let's start it right here right now and have it randomly go this way. I'm going to say x equals, x minus equals one, y plus equals some random number between negative one and one, alright. So let's do that. And then let's make a particle. I'm going to call it current. And let's say size 600 600 for the window, and I'm going to make a new particle, which is going to start at 600 comma zero, and I'm going to say background zero. Current dot update. And then let's also write
a function like show. So, I'm going to write
a function called show and let's just draw
this as, it'll be white with a white outline and this should probably have a size too. Let's give it a radius and then I can just set that always to be, like, three. I don't know, I'm making this up. Ellipse, x comma y r times two r times two because the radius is, the
diameter is the radius times two. Alright, so now if I were to say, oh, this should be good. Oh there it is. There it is, it's
wandering around up there. Okay, so one thing I want to do is I really, this is
going to work much better, if everything can be
relative to the center. So I'm going to translate
zero zero to the center. Let's do that. Translate width divided by two, height divided by two. And then the particle
should actually start at width divided by two 'cause it's that far out. It could start further out, but, and now we can see, there it is. There's my particle. Go, go particle. You can do it. You can make it to the center. Okay, it's just going to keep going, so there's, I need some
way of telling it to stop. (laughter) So, let's say if current dot finished, then what I want is I
want to have a big array, I mean, I could just not erase the, I could render it to, like, a separate graphics object or something, but let's, this'll be
the less efficient way, but let's make an array list that is full of particles. Let's call this the snowflake. Snowflake equals new, what was I saying, array list. New array list of particles, and then if it's finished I'm going to say snowflake dot add the current particle, and then I should remake
the current particle again, like I should make a new current particle. And then I also should for
every particle p in snowflake, I should show them all. So the idea here is that I
have this particle wandering. As soon as it's done it
gets added to the list and a new one starts wandering. So I need to implement
this finished function. As you can see this read squiggly is like I don't know what that is. What does it mean for a
particle to be finished? And I can say boolean finished 'cause I want this function
to return a boolean variable. I mean, yeah, a boolean
value, true or false. Return x is less than zero. So it's finished when x is less than zero. Obviously I'm going to have to get more sophisticated than that, but that will be a good start. So let's see here. Go particle, go. Go particle, go. Go particle, go, stop. Go particle, go. Go particle, go. Go particle, go. Go particle, stop. Okay, so that's good. This is kind of working. I actually, I really
kind of want to reflect, do the kaleidoscope thing
now so we always see that. Oh that'll be so fun. So the particle is finished if also, if it's, if it's past zero or if intersects another particle. So, I guess I could say,
if current is finished or current intersects
snowflake, the existing. So now I need to write also another function called boolean intersects and does it intersect, the snowflake is just
an array list, right. (groans) A particular snowflake. And then let's just put a
return false here for a second, make sure this is still working. So it's still working,
it's never going to stop. But now it will also, if, okay, I'm thinking, I'm thinking, it's so hard to talk and code. If it intersects itself, like, I have to just check every
other snowflake against it and current is not currently
in the snowflake array so I don't have to
check it against itself. So, I'm going to assume a result, I'm going to assume it's
not intersecting anything. Then I'm going to check everything for particle s in snowflake if, and then I just
need to get the distance between s x, s y, and
this x, and this dot y. By the way, I should
mention I have this thing (upbeat music) where I always forget
the this dot, this dot, but actually in Java,
the this dot is assumed, but in this case I kind of felt like I wanted to put it in there, 'cause I want the distance between s dot x and this dot x, this dot y, but I don't actually need it. So that's what I'm doing. And then I'mma say if
the distance is less than the radius times two also, then result equals true. And I can also break out
of the list, the loop. Like I don't need to keep checking. I can say break and then return result. So now, this should get me, that it's going to stop if it, if it intersects another
dot or gets past zero. Come on, oh! So exciting, it worked. Go, go, go, go, go, this is like so slow. So this would actually be, it's sort of interesting to think about whether we want to animate this or not. Great, so this is working. What I want to do right now, let's, let's do the crazy thing I want to do, which is kaleidoscope it. So I want to actually now
while this is happening, I want to reflect it along this axis and then also rotate it around six times. I think six is the right number. I'm not really sure. Okay, so in order to do that it's really all about here and here. Let's see, how do I want to reflect it? I could use the scale function, right? Like, push, let's just use
push and pop just in case. Pop, scale one negative one, like would that reflect it around the, whoops. Oh, changes. This used to work and now it doesn't. By the way, it's push and pop in p5, but in Processing it's
pushMatrix and popMatrix. Is this actually going to work? Oh yeah, look at that. It's reflected around the x-axis. That's pretty cool, right? So that worked. Then what I want to do
is, in addition to that, I also want to do this six times. So I'm going to say for int i equals zero, i is less than pi divided by, oh two pi, no, no, i is less than six. Let's just use an integer, i plus plus. Then I'm just going to say rotate pi divided by six, right? Oh that's wrong. Rotate pi divided by three. There we go. Cool! So now, we've got it kind of reflected and kaleidoscoping. Oh, this is fun. Alright, so you can see how this is, by the way, were kind of done. (laughter) It's just a matter of, there's a few things I think that are worth cleaning up here. First of all, we're really going to have to wait a really long time watching it, although I really do like this
kind of animation idea of, like, watching it build up over time. But there's also kind of an issue here, like I really should constrain, like I, this thing that's moving this way, I think I want to constrain
it within this slice. Like I don't want to let it
to go outside of the slice. So in order to do that while it's moving, updating, I should, this is why it would've
been good to use a vector. Let's actually change this. I'm going to say p-vector position, and I'm just going to
call it pos for position, and then I can also make this x and y. And I'm going to say pos
equals a new p-vector x and y. And then I'm going to
say pos dot x, pos dot y, and pos dot x, pos dot y. And then s dot pos dot x. Might be a more elegant way to do this. Pos dot x, pos dot y, and pos dot x. Okay, so this should be the
same as what I had before, but what I like about
this is I can actually get the angle now. If I have it in a vector, I can say the angle equals
position dot heading. And then what I could do
is I could basically say angle should be constrained between zero and pi divided by six 'cause I kind of want a 30
degree angle there, I think. Oh, and I want to constrain the angle, and then I could just make a new vector. So if I say the magnitude
is the magnitude, and then I can re...,
there's probably a way to like rotate the vector
without making a new one, but I can really just say now pos dot x equals magnitude. I mean I could make a new vector. Pos equals p-vector dot from, from angle angle. And then pos dot set mag magnitude. So this is not a very
efficient way of doing this because I'm making a new object, but basically I'm just
taking the existing vector, whatever it is, like if this is it here represented as this arrow, I'm basically constraining
the angle to here and then making a new
vector that looks like this, so as it's wandering,
it can't go past here and it can't go past here. Let's see if that works. I mean, it's sort of hard to tell, but it's going to, you know,
is this really different? I think we might see the difference if I were to speed this up. Oh, weird. Oh I think I know what the issue is. It's never going to go past zero, right. I think it's never going to go past zero because I'm constraining the angle so even if it gets past
zero, I put the angle back. So look at this, it's never
going to get past zero. Eh, let's just make it less than one. Let's make it never go less than, where is that in update, in finished? Yeah, let's just say less than one. (chuckles) Okay. And ngramptz in the chat says do you think randomizing
the starting position? Yeah, I definitely should
randomize the starting position, I think that'll be more interesting. Okay, so this is working, working again. Let's speed this up. While current is not finished
and it's not intersecting, so I could like, I could basically put a while loop here in
draw that's basically saying, like, keep updating. Update, update, update until you're done. Let's see. Oh yeah, there we go. Hey! (rings bell) Ta-da! That's cool. Wait, why is it... I don't like, hold on. I feel like it doesn't
look very snowflakey. We should rotate pi divided by three? Yeah, no. Pi divided by six? There we go. That's better. It should be, that line
should be vertical. And you're right, it's not very, it doesn't branch out so much. Let's try some things. One thing would be we could kind of let it wander off further. Yeah, that's kind of cool. It's also the other thing
that's happening here is it's, just like, it's never ending. It's never ending. So what if we, okay. So let's randomize the starting position. So, again, if I were being sort of smart, smart, probably the best way to do this, I don't know what counts as best, but it would probably make sense for me to kind of randomize the starting position along the path of this kind of circle of radius width, and then randomize a starting vector maybe that points towards the center. But I think I can get the same effect, loosely the same effect by just, kind of, randomizing the height. So like what if I let it start
between zero and 10 pixels. Yeah, that's kind of nice. I mean, this is very snowflakey. (rings bell) Okay, one more thing that I'm going to do, let's just make this full screen. Full screen. Let's, oh, we should probably make this height divided by two because, oh that doesn't
actually really matter, width divided by two. Let's try it. Alright here we go, full screen. Alright, here it is. Here is your, whoa it's crazy 'cause it came out from so far. Here is your snowflake generator. (blows flute) This is my in Processing Brownian Motion Diffusion Limited Aggregation
snowflake generator. There is so much you could do now, right? You could start to think about color. You could start to think
more about the sort of, like, what if it were a vector and you play with the velocity or how you could constrain it, how could you animate
it in different ways. But this is the basic idea. Here we go, we now have
a snowflake pattern generated very fractal
kaleidoscopey like thing for the holidays. Make your snowflakes. Maybe you could even do something where you make these much smaller and save them as little PNGs and then you have, you generate, like, thousands of different snowflake patterns. Alright, I'm sure you will come up with some interesting
improvements on this. Please check the video's description for a link at the coding-training.com to where you can submit
your own version of this, and also there'll be a
JavaScript implementation there, and I encourage you if
you enjoyed this video to consider supporting
the Processing Foundation. Processingfoundation.org/support. It could use your support. Thank you very much and goodbye. (rings bell) (upbeat music)