Coding Challenge #86: Cube Wave by Bees and Bombs

all right this is my first coding challenge that I'm going to attempt in JavaScript using 3d rendering I am currently working on a set of tutorials about WebGL in p5.js I will link to those from this coding challenges video description but I bees and bombs on Twitter I highly recommend if you're interested in looking for like really geometric algorithmic mathematical illusion gifts that will kind of blow your mind check out the bees and bombs Twitter feed and look at this oh yeah look bees and bombs is watching this right now this is the gift I'm going to try to recreate in p5.js using the WebGL renderer okay so we'll see how this goes I'm just gonna get started so first I'm actually gonna just work in 2d because one thing that I need is just this night and I really need this in my life breathe in breathe out breathe in meditation I'm very high strong I really think to work on meditation and this is actually a nice calming soothing gift so I need something that can give me that oscillating behavior and the sine function simple harmonic motion the swinging of a pendulum the plucking of guitar string I do have some other video tutorials about that in processing and I will also link to from this video so first let's just make that happen in 2d so what I'm gonna do is I am going to have a variable I'm gonna call that variable angle and I'm gonna stick I'm not gonna I could add angle mode degrees to think in terms of degrees but I'm just gonna stick with radians I'm gonna say angle plus equals 0.1 then what I'm going to do and because once I get into WebGL mode the center zero zero and WebGL renderer is the center I'm actually just going to quickly translate to the center because I want to just do this in 2d real quick and let's draw loops let's draw let's say a rect mode Center and let's draw a rectangle so I want to draw a rectangle who which position is zero zero and its width is some arbitrary thing like 10 and it has some height so if I were to say let H equal 100 we would sorry we would add them in the wrong place we're gonna do here okay so that's that's one of these days I'm gonna be able to move between these okay so let's add a background that's black and let's add a fill that is 255 okay come on there we go there we go so there's that rectangle so what I want to see it now is breathe up and down oscillate up and down so the sine function is a function that will give me a value between negative 1 and 1 if I were to graph the sine function and the x-axis here I could think of that angle that's increasing over time I would see a curve like this and that curve is going to oscillate between plus 1 and negative 1 so I could certainly use the map function to and actually probably will I'll use the map function the math is not that complicated so I could take the result of the sine function it's a variable value and if that's between a range of negative 1 1 and I could map that range to 0 into between 0 and 100 of course I could just like multiply it by 50 and add 50 but let's use the NAP function why not it's there in p5 so I could say H is now mapped sine of the angle which has a range between negative 1 & 1/2 between 0 and 100 and what we should see now is this so this is the behavior I believe this is simple harmonic motion there's so much that you could do with this right think about layering these all moving at different rates offset from each other with different colors and sounds you know the world is your oyster now and what you could do is like simple harmonic motion but here what I'm going to attempt to do is I'm going to attempt to try to create this now actually I still think maybe I'm not ready for 3d because I think what I want to be able to know that I can do is put a bunch of these in a row all oscillating offset so can I take it make a 2d version of this first let's see if I can do that so how am I going to do that well I could need a loop so let me say X equals zero X is less than with X plus equal and let me go over by 10 pixels and then let me draw each one of these rectangles at X and I'm going to draw it with a width of 9 just so I can see see it in between so this okay so oh I forgot that I translate it to the center so please go away terminal so what I want to do is start X at well I'll just say X minus with divided by 2 here whoops what do I have wrong line 13 4 let X equal 0 right okay so there we go now I have a whole sequence of these oscillating but obviously they're all oscillating together and if you see here they're all oscillating slightly offset from each other so what do I need I need an offset so let's make a variable called offset set it equal to 0 and I'm gonna say I mean let's I just wanna let me just say let a equal angle I'm just going to break this up into multiple lines of codes I think that makes things a little simpler so this is this is the same thing but now what I'm going to do is say angle plus offset and then that offset is going to change for each one of those and maybe let's just I don't know let's just try offsetting by the same amount that the angle is increasing so they're all just one step ahead at the previous one there we go now this has a totally different look to it and it's actually like kind of it looks like it's almost like this shape moving to the right I mean I don't know I think we could start to play should probably like hook up some sliders here like with different values I'm gonna get different sort of things like is but is this the right idea it's so funny because it really looks like this thing moving but what is it and maybe I if I make these thick like could I have less of that yeah there we go so you can see this it's really an optical illusion you know by how I play with the size and where there and also like the X should start so I need some more variables here let me make a variable called W which is the width of each one of these and I'm going to set that equal to 24 and I'm gonna say W minus 2 just to give a little buffer between them and then this is also where they start is wrecked X minus width divided by 2 plus W divided by 2 and let's have the offset just be perfect again now we can see there we go so what you can see this is all that now in the B's and bombs GIF there certainly is this sense of the center going up and down rippling out to the outside so I might need to think about like how where what angles are starting where the offset is and that sort of thing but I think this is close enough so let's try moving this to 3d ok so a few things I want to do first thing first let's just add WebGL and let's just take out this translate dare I say if WebGL mode works the way I hope and dreams will work I'm actually gonna see the same exact thing right all I did was change the renderer I'm still drawing everything as 2d shapes I just changed the renderer and now I don't have to translate because by default the renderer thinks the center is the center the center of the canvas is zero zero all right so I'm not seeing the shape so let's just see let me change the background here yeah oh whoa first of all look how slow this is crazy how slow it is and the reason why I wasn't getting the the color proper is because well I really shouldn't be using these the rectangle function here in 3d so let's see if we can figure out let's try to make this a little better right now first of all let me put boxes in each in this spot so what I'm gonna do is I'm gonna say push I'm gonna add push and I'm gonna add pop and what I'm going to do is I'm going to just translate by the x-value zero zero and instead of drawing a rectangle I'm going to draw a box of that size so let's see what I get okay oh and incidentally now what I need to do is I need to translate X minus width divided by two so they're all those these are all boxes there are 3d boxes you can't see that they're three T because they don't they I've just seen them from the side but you'll have to bear with me here just to prove that they're 3d what might be worth doing is just saying something like rotate X by that angle so that angle that's affecting this side so we can see that they're there I'm gonna leave that in there just so that we can see this like slow rotation of the scene and I'll even slow it down by like a quarter so what I want to do now is let's see if I can how do I effect the heights only of those boxes so the box has a width a height and a depth so I want lips with the depth I'm just gonna have V W as well so the width and the depth which is along the z axis and the H is the height so let's try doing that there we go now they're spinning Wow look at this I think I'm getting somewhere wow this is kind of crazy looking oh let me take out that spinning let me move the whole thing down a little bit and let me zoom out from it a little bit so I'm gonna translate like everything down like 25 pixels and out like 50 pixels so we're kind of like zoomed away from it I want to see it from above a little bit so if I translate it down even further I guess I need to think about maybe the camera but or I might I could like sort of like rotate everything by like a slight amount like so I want to rotate along the x-axis by like 45 degrees or something oh no I wanted to say rotate X and I want to do it the other direction there we go so I just wanted to get some view on it that somewhat resembles sorry I lost this particular view now one thing you'll notice have you ever played the video game Qbert well what I what this looks like to me I believe is something called isometric perspective or no no no oh yeah orthographic perspective let's look at the p5.js reference for a second reference perspective yeah perspective perspective is a function that kind of says like hey this is where the Candice is what the camera can see this is its view of the world and actually what I want is this function ortho which sets up now there's not a lot of documentation here but it sets up so let me see if I can like orthographic perspective let me do an image search so this of–this is perfect so you can see this is a really nice image here to kind of demonstrate the difference perspective projection has this realistic view of sort of distance and of all of the this idea of like perspective of drawing if you were trying to learn a drawn perspective of how the lines come together to a point where as orthographic projection so perspective is the wrong word I'm saying orthographic perspective that's not right the idea here is the projection creates this highly uniform look and the video game Qbert is probably the most famous sort of example of this kind of orthographic projection so let's add earth graphic projection so I can give it a like a clipping plane or a sort of it's called a frustum like the bounding box of what I want to be able to see with orthographic projection or isometric projection but I think by default if I just say ortho it's going to change and we hit refresh and whoops let me put okay so yeah so you can see now it looks very flat now I need to be able to start to see the different sides of different colors so let me see if I can add maybe at least some directional lighting maybe let's see if I can just add some lighting from the top let me just say directional light 255 and let me add the light from the top so 255 255 255 and then I want the light to point down which is zero negative one comma zero so let's see if this gives us at least some shading mm-hmm and what if I did I probably still have fill in here ah right so I need to fill it's going to take over I need to just give it an ambient material ambient material will allow the box to be affected by the light there we go and I can make the oops and I want the light to be white and we make a make the background black yeah so I'm not really getting a lot of nuance here in terms of but let be let's make the boxes with a little less so there's some space okay and I want to be able to look at it now maybe I should just give it ambient light I could give the different sides I'm lost now alright so how come I am let me let me try rotating how can I see the tops how can I see this shape I need to figure this out Oh ambient light by the way so I don't want to use ambient light I could try a point light I'm looking I'm thinking I'm trying to maybe I'm gonna get a suggestion from the chat I just want to let me let me give it a normal material so normal material is a useful material for debugging because it just gives it an RGB colors to all the different vertices of the shape based on their XY and Z values let me give it normal material alright so actually I think this is doing what I wanted to do now I'm seeing the orthographic projection and I and the normal material is giving me RGB colors for all the vertices but let me let me make the background 100 just so I can really see that there we go so this is actually I'm now looking at the correct thing but I'm not actually looking at isometric view here's the thing no I'm gonna leave this like this right now let's try to nest this Luke and let's have a bunch of these so what I'm going to do now is also add an inner loop let's add an outer loop let's add an outer loop for Y and what I'm gonna do with why now is translate Y – height / – okay and let's make the depth also a little bit smaller just to have some spacing there so okay X is not defined where oh this has to be Y thank you okay all right now is this doing what I wanted to do is it doing what I wanted to do and I just and I just a weird sort of view of it so let's try to start altering let's let I want to see what's going on here a little bit so what I'm gonna do actually is rotate X by that angle whoa I've really freaked it out let me take this out let me let me make this just fixed so what is going on for every X for every Y draw a little box okay oh they're all just right next to each other in a line Oh cuz I don't want to I don't want to go along the Y Pilar probably time and I need to use Z of course Z I'm not I'm not of course I need to the Z plane is what is allowing me to create this grid of them Y is what's moving up and down so oh I apologize for this so I'm actually gonna do Z I'll just leave height I'm gonna just I'm going to change the variable to Z though just because I feel like it's gonna be confusing and now yeah we should we see now I have this grid of them and I'm kind of spinning around it in a weird sort of way and what I'm going to do here is and I actually don't need this offset to subtract backwards I don't think Oh actually no that would be good to keep that in there okay what I want to do now hold on everybody is let me take this out okay now there's this plane of them let me put H back in and interestingly enough what's going on here sign Oh angle equals angle plus offset so I want the offset to happen right now just per per row okay so I see this whole row going up and down all right now here's the thing I need to be able to look at this I probably should have done this before I really should have done this before but if I look at isometric perspective actually to see isometric perspective what I need to do is first rotate by 45 degrees all about the vertical axis which is X so I'm going to let's get rid of this translate which i think is unhooking leave that in there I don't need rec mode Center I'm gonna rotate X – quarter PI which is 45 degrees let's see what that looks like all right that's kind of interesting what's going on here now I want to I I'm kind of looking at it from this weird like top to you I want to turn it so the next thing I want to do is rotate by Y of and let's look at this arc sine or arc tan so I could do one of these so I'm going to do arc tan of 1 divided by the square root of 2 and I should make this a constant somewhere that I save let's do let's call this magic angle and say let's call this I'm just gonna call this MA for magic angle ma equals a tan of square root of 1 divided by square root of 2 so let's now rotate Y by that Thank You Alka for having suggested this there we go ooh okay we're in good shape here look I'm seeing this now here's the thing I've got a clipping plane issue like I'm not actually able to see the whole thing so let's deal with that I can with ortho I can say this is the range what I want to be able to see so I want to see between negative 200 and 200 between negative 200 and 200 on the Y and then I want to be I just want to be able to see like a lot along the Z okay that's everything and maybe I should zoom out a little bit just so it's a little further away from me hold on let's get rid of this translate and let's let's say 0 to 500 there we go I think then alright oh it's like I've turned it over also boy what a mess so maybe this should be 200 and negative 200 there we go ah kind of getting somewhere look at this kinda getting somewhere okay now I need to deal with my clipping planes and I actually think it might be getting clipped in all whoops there we go I want to look at it from further away so I'm gonna create that so that was too much 300 let's try 300 and boy I could make these variables would really help there we go okay so I'm seeing this thing now it's kind of like a little bit off weirdly okay it's a little bit off weirdly and so what am I missing am I is this just need to be is it is that the Z that's getting clipped yeah okay so now I see the whole thing I see the whole shape now what I need to do is figure out the offset and what I think I could do if I think about this is the offset is not a value related to along the X or along the Y but how far it is from the center so what if I were to come back here and inside my loop have some kind of distance value be the distance between X and Z and not zero zero but with divided by 2 and height divided by two that's how far their I I feel like I should actually have just translated this whole thing off so I would made it easier but because I have all this like offsetting so that's the distance and instead of having this offset like increase what if I just say offset equals map that distance now what's the range I probably should figure out what the maximum distance is the maximum distance is max D is going to be the distance between the center and to under 200 really right that's kind of like the maximum distance so D has a range between 0 and max D and I want that offset I'm just going to make up something between negative 1 and 1 like I want an angular offset for each of those now let's look at this oh it's so slow but this is the right idea right so let's let's make this let's try to make this run a little faster boy boy p5 so there's probably lot of optimization that needs to be done for because we certainly can do this in WebGL we're all going to remake this so a couple things I want to do one is let me make this we make them bigger what is the slowdown okay that's a little bit better now I want this what its mapping to in terms of the height to be a lot taller yeah so I could I need to do some work with like pre saving all the geometry but then I'm getting Elka's making a good suggestion okay so I have to go this challenge the challenge is over let's have the offset be more twice as much there we go Hey look at this pretty close right pretty pretty pretty close so what have I not done what is I really need to deal with optimizing this one reason it's running so slow I think is actually it's kind of unhappy with having these floating-point numbers for the height of the box so I think if I change this to a two-floor the values but I am getting some weird artifacts here and that's actually if we look at the B's and bombs you'll see that it doesn't actually go to 0 it goes between some set of values so it goes between maybe like 100 and 300 let's try that whoops there we go so that is much more like now could i zoom out on this more so one way I could do that is by translating I don't know if this makes the most sense to do let me zoom out a little bit no you know what I need to do is just change the I think I need to be more thoughtful about the orthographic view okay so I zoomed out a little bit and make more cute let me make more cubes now so let me change this back to like 24 there we go how am i doing so this is moving faster and that offset is even more so let me let me map the offset and actually yeah negative three let me let me just I mean I probably should be thoughtful about this and have that offset be like you know some actual like angle well but that's half PI actually let me just have it between negative PI and PI let's try that there we go this is starting to look good and okay and now let me have it go a little bit faster here's the thing here's what's missing and I'm going to leave as a challenge for you the viewer number one is I've got the perspective slightly off here something slightly wrong right I don't have my angle exactly right right why is there this weird kind of like diagonal there it's also in Reverse everyone's time it's in Reverse so this has got to be an easy way to fix that oh yeah whoo that's kind of nice it's a little bit too fast [Applause] okay get all the way there but I got pretty close and so the challenge for you the viewer is to fix my mistakes something about the perspective is off I probably need to think about you know the speed and I might like to color use lighting to make it more beautiful what other types of 3d shapes so I'll rotate X after rotate Y can I just do this in the wrong order whoa that's kind of cool something different okay I got to go thanks for watching this coding challenge and I'll see you all later

24 thoughts on “Coding Challenge #86: Cube Wave by Bees and Bombs

  1. Ok, the reason why the isometric view is off is because you did the rotates wrongly.




  2. Holy cow. you can program so fast! I made the same thing in C++ and OpenGL, and it took me nearly a day. Most of the time I'm just thinking what to do next in my code, and you just keep going somehow. How do you do that?

  3. It seems to have a kind of circular offset, hence I think you could do it based on a circumference centered at the origin, having the main box at (0, 0) you could make the offset to be sqrt(x*x + y*y), make the height function a cosine so the center box starts at the top, and the offset would increase based on the distance from the origin to the current box. It could also be multiplied by a constant, so you could control the offset difference between the current box and those adjacent to it. By the way, this was a pretty interesting video

Leave a Reply

Your email address will not be published. Required fields are marked *