I don't understand maths in Mandelbrot set

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.

2 Likes




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
image
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:
image
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
image
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
image
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
image

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
image

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:

image

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:
image
Assume that the sequence starts at 0
a_0 = 0
Say I wanted to find a sub 1
image
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
image

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
image

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
image
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

image

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

image

But yeah thats mandelbrot set very cool

17 Likes

Thank you very much :slight_smile: !
I wouldn’t do anything without you!
Now i have basic understanding of complex numbers.

1 Like

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.

1 Like

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.