I want to script Mandelbrot set. But I don’t understand maths in it and I don’t know what complex plane, iterations and z are in mandelbrot set.
IVE RECREATED THIS TUTORIAL WITH HIGHER QUALITY IN #COMMUNITY-TUTORIALS, PLEASE REDIRECT YOURSELF THERE RATHER THAN HERE
HYPERLINK TO NEW TUTORIAL
The complex plane is a very interesting topic thats useful for countless things
The complex plane adds onto our normal set of numbers a second dimension
If you think of a normal number line:
It just goes -5 -4 -3 -2 -1 0 1 2 3 4 5 obviously
This is what you have used since probably 4 years of age
Normal numbers are going left to right on a number line
Complex numbers are going up and down on a number line
Similar to math class, the complex plane is like the cartesian plane with X and Y coordinates you probably use all of the time in math class
Where X is left and right
And Y is up and down
Regular numbers are like the X axis
Complex numbers are like the Y axis
Regular numbers are normall formatted like 1 2 3 4 …
Complex numbers are in terms of the letter “i”
i has a value of √(-1), and is like “1” on the Y axis
2i has a value of 2* √(-1) and is like “2” on the Y axis
Similar to how you use Coordinate Pairs for the cartesian plane, like how (5,2) represents 5 on the X axis and 2 on the Y axis, the complex plane uses a similar system
As you can see from this graphic, you simply add the normal and imaginary components to get a coordinate position
Complex numbers have some strange and useful attributes
Adding complex numbers is pretty normal
(3+5i) + (2+2i) = (5+7i)
You quite literally just add together the components of the position
This is exactly how addition works in the cartesian plane too
(3,5) + (2,2) = (5,7)
Where things get really interesting is multiplication:
If you recall, i = √(-1)
So:
If you take 1, and multiply it by √(-1), you get √(-1), or i
If you take √(-1) and multiply it by √(-1) you get -1, or -1
If you take -1 and multiply it by √(-1) you get - √(-1) or -i
If you take -i and multiply it by √(-1) you get 1
Notice this very epic behavior
If you recall:
1 is right
i is up
-1 is left
-i is down
Multiplying by √(-1) or i rotates the number by 90 degrees on the complex plane
Consider the following horribly drawn image:
This action isnt limited to 90 degrees at all, and can represent all kinds of crazy rotations, which is why its so useful for programming math
Consider the following set of examples:
I am multiplying red * blue = green
So obviously, limited to the normal numbers 2 * 3 = 6
(Please excuse the small inaccuracies, its about 6 because Im bad at dragging points)
Another normal example would be something like 3 * 4 = 12 so I set red to 3 and blue to 4, and green should be at 12
And it is, very epic
Ok so now heres where it starts getting complex, pun intended
Imagine two numbers on the complex plane, 2+0i and 0+i and imagine blue is 2+0i and red is 0+i
So blue is 2 on the real axis and 0 on the imaginary axis
Red is 0 on the real axis and 1 (or i) on the imaginary axis
Now imagine multiplying them
If they were both on the real axis, you would get 2*1 = 2
But remember, i rotates stuff 90 degrees
So you get 0+2i which I find quite beautiful
Note that 90 degrees isnt just some arbitrary number
90 degrees is 90 degrees because i is 90 degrees from 1, just like how y is 90 degrees from x
If I put red at 45 degrees, 2 would be 45 degrees too
In fact, anywhere you put the red it will rotate it that much
https://gyazo.com/acd6eaba9efa5c94a8d9202e8bfb85de.mp4
So here is the basic behavior of multiplying complex numbers:
The distance from 0,0 MULTIPLIES
The angle of red and blue ADDS
If red is at 45 degrees and blue is at 0 degrees (like in the above example), the final point will be at an angle of 45+0, or 45
If blue is at 45 and red is at 45, the green will be at an angle of 90
This is the beauty of complex numbers
Mandelbrot set
Now that you have a basic understanding of complex numbers, I will now explain the mandelbrot set
The mandelbrot set is represented with this equation:
This looks really confusing, but can be made sense of
Assuming you dont have prior knowledge of sequences, z subscript n basically means the nth term in a sequence
Let me start with a more simple sequence:
Assume that the sequence starts at 0
a_0 = 0
Say I wanted to find a sub 1
a_1 = a_0 + 1
This means a_1 is 1
The set of this sequence would look like
1 2 3 4 5 6 7 8 9 10 11 12 13 …
Where 1 is a_1, 2 is a_2, 3 is a_3 etc
Lets try another example
Lets say b_0 is 1
b_1 = b_0 * 2
b_1 = 1 * 2
b_1 = 2
Then lets try b_2
b_2 = b_1 * 2
b_2 = 2 * 2 = 4
b_3 = b_2 * 2 on and on
The sequence of b_n+1=b_n * 2 would look like
1 2 4 8 16 32 …
Now lets try the mandelbrot set equation
z and c are both positions on the complex plane
z_0 is 0+0i, so thats what we start with
Lets say c is 1+1i
So we do:
z_1 = (0+0i)^2 + (1+1i)
(0+0i)^2 is the same as (0+0i) * (0+0i), which is obviously just (0+0i)
z_1 = (0+0i) + (1+1i)
Remember how complex numbers add, its just like normal coordinates
z_1 = (1+1i)
So now that we know z_1, we can find out z_2
z_2 = z_1^2 + (1+1i)
z_2 = (1+1i) * (1+1i) + (1+1i)
Lets go back to our calculator for this
I input 1+1i for both the red and blue
I, in return, get 0+2i
Lets plug it in
z_2 = (0+2i) + (1+1i)
z_2 = (1+3i)
This continues on and on and on into z_3 and z_4 and z_5 and z_6
If this pattern continues growing up to infinity, it is NOT part of the mandelbrot set
If this pattern loops around again and again and doesnt reach infinity, its part of the mandelbrot set
Anything inside of the blackness is a position, c, that would not continue onto infinity
Anything outside of the blackness is a position, c, that would continue onto infinity, therefore is not part of the mandelbrot set
Ok so honestly
I dont own a NASA supercomputer and neither do you
We need to set some limitations because we really cant calculate if it goes to infinity, it could take up to z_100000000000000000000000000000000 to reach any actually conclusive result
Lets calculate up to, lets say, z_10
If z_10 is within lets say 4 units from 0,0 we’ll call it a mandelbrot point
If its outside of 4 units from 0,0, we’ll call it “infinity”
I know its not even close to the real mandelbrot set, but its a general estimation
This is way too much work to do by hand, so lets start on some epic code
Sadly, lua does not support complex numbers, but we can represent them with certain functions
Rather than using 1 and i, I will just be using x and y under the Vector2 class to simplify things
In case you dont know, Vector2 is just a thing that holds an x and y coordinate
Vector2.new(5,5) would represent 5+5i
Vector2.new(1,3) would represent 1+3i
Etc
So lets begin with the multiplication formula
We can use some math to accomplish this
If you were multiplying two complex numbers, a and b, you would use the formula
Vector2.new(a.X * b.X - a.Y* b.Y, a.X * b.Y + a.Y * b.X)
This formula is by people a lot smarter than me so Ill just be using it without explaining it
Lets translate this into lua
function complex_mult(a,b)
return Vector2.new(a.X * b.X - a.Y* b.Y, a.X * b.Y + a.Y * b.X)
end
Ok bam we got it
Now for addition, we can just use the built in addition by roblox, vector2+vector2 because it behaves the same
Lets now create a mandelbrot function in lua:
function complex_mult(a,b)
return Vector2.new(a.X * b.X - a.Y* b.Y, a.X * b.Y + a.Y * b.X)
end
--z_n+1 = z_n^2 + c
function mandelbrot(n,c)
if n == 0 then
return c --when n is 0, we can assume that z is 0,0 so therefore z_1 will always be c
end
local previous = mandelbrot(n-1,c) --we must calculate the previous z_n
return complex_mult(previous, previous) + c --formula
end
Now we must do the actual checking of points
I will be using a simple part display for the mandelbrot set
I will go through every x and y coordinate from -4,-4 to 4,4 with a resolution of like 0.1
This can be accomplished with a basic set of for loops
for x = -4, 4, 0.1 do
for y = -4, 4, 0.1 do
--10 is the number we arbitrarily determined, we will calculate up to z_10
--Vector2.new(x,y) is the complex number c represented in real terms
local z_10 = mandelbrot(10,Vector2.new(x,y))
if z_10.Magnitude <= 4 then --magnitude is the distance to 0 of a point
--we will assume z_10 will not continue to infinity
end
end
end
Ok so lets turn this into a cool display
Ill make a function that creates and positions a part in the workspace
function create_part(pos)
local part = Instance.new("Part")
part.Size = Vector3.new(0.1,0.1,0.1)
part.Anchored = true
part.Color = Color3.new(0,0,0)
part.Position = Vector3.new(pos.X,0,pos.Y)
part.Parent = workspace
end
So lets turn this into a final piece of code
function create_part(pos)
local part = Instance.new("Part")
part.Size = Vector3.new(0.1,0.1,0.1)
part.Anchored = true
part.Color = Color3.new(0,0,0)
part.Position = Vector3.new(pos.X,0,pos.Y)
part.Parent = workspace
end
function complex_mult(a,b)
return Vector2.new(a.X * b.X - a.Y* b.Y, a.X * b.Y + a.Y * b.X)
end
--z_n+1 = z_n^2 + c
function mandelbrot(n,c)
if n == 0 then
return c --when n is 0, we can assume that z is 0,0 so therefore z_1 will always be c
end
local previous = mandelbrot(n-1,c) --we must calculate the previous z_n
return complex_mult(previous, previous) + c --formula
end
for x = -4, 4, 0.1 do
for y = -4, 4, 0.1 do
--10 is the number we arbitrarily determined, we will calculate up to z_10
--Vector2.new(x,y) is the complex number c represented in real terms
local z_10 = mandelbrot(10,Vector2.new(x,y))
if z_10.Magnitude <= 4 then --magnitude is the distance to 0 of a point
create_part(Vector2.new(x,y))
end
end
end
Ok like this is actually cool
Now I want to try to increase how accurate this thing is
function create_part(pos)
local part = Instance.new("Part")
part.Size = Vector3.new(0.05,0.05,0.05)
part.Anchored = true
part.Color = Color3.new(0,0,0)
part.Position = Vector3.new(pos.X,0,pos.Y)
part.Parent = workspace
end
function complex_mult(a,b)
return Vector2.new(a.X * b.X - a.Y* b.Y, a.X * b.Y + a.Y * b.X)
end
--z_n+1 = z_n^2 + c
function mandelbrot(n,c)
if n == 0 then
return c --when n is 0, we can assume that z is 0,0 so therefore z_1 will always be c
end
local previous = mandelbrot(n-1,c) --we must calculate the previous z_n
return complex_mult(previous, previous) + c --formula
end
for x = -4, 4, 0.05 do
for y = -4, 4, 0.05 do
--10 is the number we arbitrarily determined, we will calculate up to z_10
--Vector2.new(x,y) is the complex number c represented in real terms
local z_20 = mandelbrot(20,Vector2.new(x,y))
if z_20.Magnitude <= 4 then --magnitude is the distance to 0 of a point
create_part(Vector2.new(x,y))
end
end
end
But yeah thats mandelbrot set very cool
Thank you very much !
I wouldn’t do anything without you!
Now i have basic understanding of complex numbers.
This is excellent tutorial material I think.
It’s even better than good!
Beacuse quality of that what Papa has said is mindblowing.
I was struggling with mandelbrot set for months and every my attempt was an complete failure.
You are completely right. FYI, I was referring to the tutorial category of this forum.
WOW. I cannot believe you took the time to write all this! Consider placing it in a tutorial on the devforum!
Hello PapaBreadd!
I am at awe with the level of detail you went into for this one scripting support thread. You should really consider moving this to a community resource as you did an amazing job at making it. (You could also just edit your message with a link to the new community resource!)
Anyways, great job explaining.