Placeholder Image

Subtitles section Play video

  • (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)

(rings bell)

Subtitles and vocabulary

Click the word to look it up Click the word to find further inforamtion about it