Coding Challenge 168: MandelBulb 3D Fractal

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone and welcome to coding challenge i'm slightly afraid it's the mandelbulb it's something that i've wanted to try for a really long time but i've never really thought that i could do it i think today is the day where maybe i'll be able to it's my hope that we're going to get to the point where we understand the mandelbulb able to write the code for the mandelbulb and then you the viewing audience will take it from there and make all sorts of beautiful versions of this amazing intricate fantastical fractal pattern in 3d now before i get going i want to mention two previous videos one is my mandelbrot coding challenge from six plus years ago that is the origin story of the mandelbulb itself as well as my spherical geometry coding challenge which looks at how to map cartesian coordinates in 3d space to the surface of a sphere and we're going to need that same math when taking this 2d fractal this 2d mandelbrot set and stretching it twisting it extruding it pulling it low into three dimensions now this is not a new idea the mandelbulb itself this idea of taking the 2d mandelbrot set and making three dimensions was first proposed in 1997 by jules reese but if you've seen the mandible before and it appears in popular culture i believe it's in the movie big hero 6. maybe i could show a clip of that the one that you might have seen and the one that i'm going to try to make is the 2009 version developed by daniel white and paul nylander before i write the code let's take a step back and let me try to explain the concepts behind what i'm about to attempt to do here and the place where i really need to start is the mandelbrot set itself the mandelbrot set appears as a pattern on a complex plane while a complex plane is a very fancy term for a plane of numbers that has a horizontal axis and a vertical axis the key difference here is that this complex number which has both a real component and an imaginary component involves something known as i i is the square root of negative one this is often referred to as an imaginary number because i don't know the square root of negative one i can't calculate that that must be part of your imagination but it's actually something very real in theoretical and practical mathematics saying that it doesn't exist is like saying well negative numbers don't exist because i can't actually make you negative three apples so to calculate and visualize the mandelbrot set the idea is to look at every single complex number on this plane so if i pick this number i might have a certain value for a maybe it's 0.4 and a certain value for b maybe it's negative 0.2 0.4 minus 0.2 i and the idea here is to take this number plug it into c start with z equal to zero so z iteration one equals zero plus c so now this is the new value of z so at z iteration two i get what's zero plus c is c c squared plus c and then at iteration 3 i'm going to take this value c squared plus c square it plus c and so on and so forth and the idea here is if i apply this math over and over again the result is going to either go to infinity or stay bounded it's going to kind of oscillate around a stable value so i'm examining every single point on this complex plane running this algorithm and determining whether it stays bounded or tends to infinity the set of the points that stay bounded i always get this confused but the set of the points that stay bounded is the mandelbrot set if i color all of those points black and all the other points that are not part of the metal bar set white i will see this fractal pattern so if this is the mandelbrot set what is the mandelbulb the mandelbrot set is inherently a fractal that lives in two dimensions instead of a complex number could we use something called a triplex number after all a coordinate in three-dimensional space has three components to it x y z so there's there's plenty more to this story here that i want to map out some of the math to but i think this is a good time to just take a little pause and actually set up a processing sketch that will allow us to visualize triplex numbers or in essence 3d coordinates in space for this coding challenge i'm going to use processing it's a creative coding framework it's built in java you can download it at processing.org and i probably have hundreds of videos that talk about it but check out the website check out the processing foundation to learn more the reason why i'm using it is because it has a wonderful 3d rendering engine that exists in p52 but i want to explore this in processing first let me say a few quick things about the code i have so far size gives me a window size of 600x600 pixels p3d for 3d rendering window move is just because i'm obsessive and i want the processing window to be on the other side of my desktop here that's a new feature i don't know if that name will stay but it's working right now and then i have a draw loop and i'm just drawing a background the first step i'd like to do is just be able to visualize the voxels of a cube because ultimately i'm going to try to place this mantle bulb inside of a fixed space in three dimensions so i'm going to use a variable to talk about the dimensions of a cube i'm going to call that dim short for dimensions so i'm starting off with a triple nested loop for every i from 0 to 32 and every j from 0 to 32 and every k from 0 to 32 let's create an x y z point in three dimensional space and there you see this cube all of the voxels all of these 3d pixels points in three-dimensional space making up a cube every single point is spaced out between negative 100 and 100 along the x y and z axis and something that i can do just to make this a little nicer to examine and look at is add the processing library called pz cam pz cam will center the view in the center of the processing window itself so i no longer need this translate and then once i run the sketch i can now use the mouse to sort of look around zoom in and out of this 3d point cloud if you're wondering what that 500 is doing that's kind of like the camera position how far away am i looking at the points that i'm placing in space so making that 1500 it's quite a bit further away but i can scroll to zoom in and rotate and spin around so how do i make the leap from this value c right here which is a complex number with a x component and a y component to a triplex number with an x component y component and z component and the answer lies within something called a spherical coordinate but before i define a spherical coordinate let's review a polar coordinate first so in two dimensions a cartesian coordinate is an x y coordinate defining a position according to its placement along the horizontal and vertical axis and i can describe that same point as a polar coordinate its position is indicated as a distance from the origin r a radius and an angle of rotation theta we can describe points in three dimensions in a similar way using cartesian and spherical cartesian having an x y and z axis and a spherical coordinate being described as an r just like in polar coordinates a distance from the center but then two angles of rotation theta and phi but why do i need spherical coordinates after all for the regular mandelbrot set i didn't need polar coordinates i could just take this complex number and square it no problem so while there might be a way for me to create a version of the mandelbot set in 3d without the idea of spherical coordinates the mandelbulb that i want to make the one that was developed in 2009 uses the idea of spherical coordinates to take a triplex number and square it or cube it or put it to the fourth power and ultimately to the eighth power so we have to look at a little bit more math before i put this into the code remember the iterative formula that i'm using for both the mandelbrot set and the mandelbulb is as follows z equals z now with mandelbrot it's z squared but a more generic form would be z to the n plus c and now c is a triplex number so if z equals zero to start we have z the next z is zero to the n plus c which is just c and then the next z is c to the n plus c and the next z is c to the n plus c to the n plus c so looking at this math that i'm doing i need an answer to the question how do i calculate x y z to the nth power and this is the innovation from daniel white and paul nylander a formula for taking a vector v in three dimensions x y z and setting it to the nth power to do that requires the spherical version of that x y z vector we need the r we need the theta we need the fee if you look at that formula and wander back to this original proposal which has exactly the formulas written out here this is how i calculate r theta and phi and this is how i set xyz to the nth power i think i can start to put this in the code now i'm going to have to go back and forth between this page and the code many times so first change i want to do is while it's plotting the points it was useful to map the all the voxels out to between negative 100 and 100 i want to now keep all my numbers between the range of negative 1 and 1. then from this x y and z coordinate i need to convert that to spherical coordinates so r is the square root of x times x y times y and z times z theta is the arc tangent of the square root of x times x y times y comma z and phi is the arc tangent y comma x now there's certainly efficiencies that i could do in this code in terms of like i'm squaring numbers and doing the square root multiple times but i'm just going to pre-compute the whole mandal bulb one time and set up so i'm not going to worry about that right now do i need a loop now i need a z i need a c let me look back at that webpage oh yeah ah okay look at this i need to take get a new x and a new y and a new z now processing is wondering what is n so n is the order it is the power to which i am going to set everything in my formula z equals z to the n plus c and we can try different numbers to get different patterns but i want to start with the number eight what's a little bit unfortunate here is that i want to use the variable z to keep track of z and z and zero z one in in a loop but z is also the component of the vector x y z so i think i need a new variable name for this what if i make it a vector and call it z zz so it's zz [Music] zeta oh people are saying zeta i love that okay let's call it zeta new variable name makes me so happy now i'm gonna do something that i really hate doing and i really hate that i'm about to do this but no i could do it a different way no i'm just going to do it the way i hate i'm going to say while true now generally speaking if you're going to say wild true you've got a problem because that's a loop that's never going to end the only way to get out of a loop that's looping while true the hard-coded value true that can never be changed is to put a break in somewhere so i need to remember put that break in there else i'm gonna have an infinite loop and everything's gonna crash and we're just gonna throw away all this footage and i'm going to be done never come back to another challenge ever again and just to set myself up for success i'm going to make a variable called max iterations i'm going to set that equal to 10 and then i'm going to have iteration equals zero i'm going to say iteration plus plus if iteration is greater than max iterations break now this is kind of silly because i could have just said while iteration is less than max iterations but i don't know this is the way i'm doing it we'll clean it up later this int n equals 8 does not need to be in this loop i mean it honestly could just be a global variable but i'm going to put it up here just so i have all the variables i want to mess with the order of this stuff is going to be important so zeta starts at zero and the very first time i'm taking zeta squared and then adding c to it so could i make a vector that holds the spherical coordinate and that is c i think that's right so then in the loop zeta equals power i mean this won't work because zeta is a vector power zeta to the n plus c right this is the idea of what i'm doing i'm doing this every single time and the way that i take zeta to the power of n are these formulas so zeta dot x equals new x plus c dot x the first thing that happens is i need to get these this should be in the loop i think it's really going to help me if i have a function to convert from cartesian to polar i kind of hate that i'm using the p vector for this because i'm putting the r and x the thick and y and the the v in z which is quite confusing because now when i come to do this this is actually like c dot x oh okay i'm gonna write my own spherical class might be totally unnecessary but i'm gonna do it just let me figure this out in my own way please i'm sure i'm doing this wrong but i'll get there eventually so the function returns a spherical object it's basically just like an object that holds three values but i want to be able to name those values r theta and phi so this is spherical c is the spherical version of x y z power of c dot r c dot theta and then oh there's no this was a mistake i'm getting very close i can feel it oh can i just do this like isn't that what these are i've mixed everything up let's go back to the whiteboard c is x y z so c to the n is defined by what i did and this gives me in my code new x new y new z then i add c the original x y z to it and then i take this convert it to spherical and do it again to the nth power okay i s when i said it over there it made sense in my head and now i have to see if i can put that into action here won't it work if i just start with this by the way why am i getting weird little errors here the variable r does not exist oh i have to define these variables i think this is fine because i'm starting with zero so the spherical coordinate zero zero zero is going to be 0 0 0. so i could go through this then add x y z to it and then get the new spherical coordinate put it to the power of n then add x y z to it again et cetera et cetera i think this is good i think i've got it sorry to interrupt i really just had to come from the future to acknowledge the fact that this variable c is really unfortunately named if you look at the formula for the mandelbulb itself z equals z to the n plus c there's a c in there yeah but it's not that c why did i call it that c the actual c the constant is the triplex number x y z that i'm adding iteratively each time through this loop that spherical coordinate is just the spherical version of zeta so this maybe is a more accurate way to write it not that these variable names are that great either but it's better than putting a false c there so the rest of the video is going to continue with the c there but i hope in case this was a point of confusion for you that this helps a little bit as you were let's just run this code why not it's not going to visualize anything let's see if i get any errors all right and if i were to say like if i were to multiply these i mean i could just use scale but this math is going to work for every for every pixel there okay i think we're getting somewhere so now i just need to figure out and am i in setup no i'm in draw so here's the thing i don't want to calculate the mandelbulb over and over again so i think what i want to do is take this code and put it in setup then what i'm going to do is i'm going to create an array of all the points that are within the mandible set itself that'll be an array list of p vectors in other words if at this point instead of drawing a point i just say add new p vector and i should do something better than just multiplying each value by 100 but that'll be good enough for right now right so right now i'm adding every point i'm doing the mandible math but i'm not checking what the outcome is i'm just doing the mandible math and adding every point into this arraylist then in draw i should still see that cube okay now all i need to do is determine whether or not i should add the point as part of the mandelbulb set itself so i'm only going to do that if i make it to max iterations if i make it to max iterations that means it is bounded i haven't gotten past some large value so i also need to test if i've gotten to some large value how do i do that well i think the easiest way for me to do that would be to check r r is like the distance from the center so if r keeps going like way way way out and way way out like greater than 16 then break so now only the points where the radius value hasn't gotten past a number the number 16 will make their way into the mandelbulb set itself oh my god what is the chance that when i run the code right now i will see something that looks like the mantle bulb after being in this room for like you know i've been in this room for four hours today i mean i was thinking doing a lot of stuff before i even started coding because i was so stressed out oh everybody say your 3d fractal prayer i mean there's no way this is going to work right no chance all right i'm hitting run i can't look wait a second okay that kind of looks like i don't know kind of looks like a mandel bulby thing let's make the dimension 64. oh my goodness okay so here's the thing ah that's the mandelbulb that's the mandelbo i think that's the mandible okay i think i know what i want to do here which is that let me just make n equal to one just like that cube thing right why is that not a sphere somebody will explain this to me in the comments i thought that would be a sphere but it's running really slow the reason is well i need some kind of prop some kind of device hold on here is a basketball a little miniature basketball that really needs some air bumped into it oh no oh no it's all well it's fine i'm gonna make this into the mandelbulb what i have done i'm plotting every point along the surface of this mandelbulb basketball as well as every point on the inside so i think what i want to look for are the points at which the neighbor is a bounded point or a not bounded point right like if i'm looking at where is the edge between this basketball and the rest of the three-dimensional space let me go back to eight so basically as i'm looking at i guess k is the z axis so i can do it i can just consider every point along the z axis right before i do this boolean edge so they're going to be the when i start like the middle bulb is in the center so when i start they're going to be not bounded so as soon as i find one that makes it to the end edge is true so as long as it's not the not the edge edge is true um add it to the set let's run this yeah so that's like half the shape you can kind of see it can i go up to 128 so you can see i'm just getting the bottom half of the mandle bulb because i also need to say if it is an edge then i can say edge is false right this is like the edge variable is like a switch like first it's off and it finds a point on the mandelbulb in the mandelbulb it flips it on and and places that point now it doesn't flip that switch back off until it finds a part that's not so it can flip it off and then find the next one i think this is gonna work yeah that's a point cloud mandelbulb look at that that's a point clown vandal bomb we did it [Laughter] i mean it looks nothing like the beauty of the like fully ray traced rendered colored lit mandelbalms but my by golly my brain somehow made it from the start of whatever i started today to this and i'm very very happy the other thing i can play with is what value of n am i using and we can see here in this post that these are the shapes that i would get from the power of 2 power of 3 power of 16 whoa let's look at that n is 16 here yeah take a look at that crazy fractal death star hi uh dan from the future here let's wrap this video up dad from the past kept going down a road uh there was no train there or was off the tracks and didn't really get anywhere what i've explored here is the math behind the mantle bulb and rendering it as a point cloud so there's probably some things that you could try to do even with this like is there some logic by which you could choose different colors for different points of the point cloud could you render each point of the point cloud as not just a point but with a texture or some other kind of shape could you save all the points from out from processing and import them into something i tried my hand a little bit at this using something called mesh lab and you can see some of the sort of awkward results i'm showing you here but the manual bulb fractal fractals in general have so much detail to them that trying to turn it into a mesh isn't a particularly viable solution the most common technique for rendering the mandelbulb in its full spectacular glory is using an algorithm called ray marching in combination with the signed distance function this is a technique that allows you to render different kinds of shapes in 3d like a sphere or a cube but you can also use it to render any kind of shape or you can estimate the distance to that shape from the eye or camera that's looking at that shape but if you want to get started on learning about these algorithms take a look at the website and youtube channel from anigo quiles it is a literal treasure trove of graphics tutorials and knowledge wow so i don't want this to be the end i think i'm gonna have to just completely learn how shaders work now learn about sign distance functions and return someday i don't know you know in 10 years when you're still watching this video and i haven't done it yet please let me know in the comments i'm going to return someday to uh revisit different techniques for rendering the mandelbulb in real time maybe using shaders maybe using sign distance functions maybe just using the point cloud in a different way i don't know yet if you are able to make your own creative twist off this point cloud mandelbulb please let me know share it with me in the comments social media on the coding train website all the ways i love you all i love you for having me somehow to the end of this video i can't believe you did if you did and thank you i'll see you soon in the next coding challenge on the coding trade [Music]
Info
Channel: The Coding Train
Views: 367,700
Rating: undefined out of 5
Keywords:
Id: NJCiUVGiNyA
Channel Id: undefined
Length: 28min 1sec (1681 seconds)
Published: Fri Mar 11 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.