Skip to content

Instantly share code, notes, and snippets.

@dbongo
Last active December 12, 2020 23:00
Show Gist options
  • Select an option

  • Save dbongo/c1070607384f464612fc001121ddf13d to your computer and use it in GitHub Desktop.

Select an option

Save dbongo/c1070607384f464612fc001121ddf13d to your computer and use it in GitHub Desktop.
# The Mandelbrot Set for Ruby by Michael Crowther
#
# Based on "The Mandelbrot Set" example by Daniel Shiffman for Processing 3+
# (https://processing.org/examples/mandelbrot.html)
#
# size(640, 360);
# noLoop();
# background(255);
#
# // Establish a range of values on the complex plane
# // A different range will allow us to "zoom" in or out on the fractal
#
# // It all starts with the width, try higher or lower values
# float w = 4;
# float h = (w * height) / width;
#
# // Start at negative half the width and height
# float xmin = -w/2;
# float ymin = -h/2;
#
# // Make sure we can write to the pixels[] array.
# // Only need to do this once since we don't do any other drawing.
# loadPixels();
#
# // Maximum number of iterations for each point on the complex plane
# int maxiterations = 100;
#
# // x goes from xmin to xmax
# float xmax = xmin + w;
# // y goes from ymin to ymax
# float ymax = ymin + h;
#
# // Calculate amount we increment x,y for each pixel
# float dx = (xmax - xmin) / (width);
# float dy = (ymax - ymin) / (height);
#
# // Start y
# float y = ymin;
# for (int j = 0; j < height; j++) {
# // Start x
# float x = xmin;
# for (int i = 0; i < width; i++) {
#
# // Now we test, as we iterate z = z^2 + c does z tend towards infinity?
# float a = x;
# float b = y;
# int n = 0;
# float max = 4.0; // Infinity in our finite world is simple, let's just consider it 4
# float absOld = 0.0;
# float convergeNumber = maxiterations; // this will change if the while loop breaks due to non-convergence
# while (n < maxiterations) {
# // We suppose z = a+ib
# float aa = a * a;
# float bb = b * b;
# float abs = sqrt(aa + bb);
# if (abs > max) { // |z| = sqrt(a^2+b^2)
# // Now measure how much we exceeded the maximum:
# float diffToLast = (float) (abs - absOld);
# float diffToMax = (float) (max - absOld);
# convergeNumber = n + diffToMax/diffToLast;
# break; // Bail
# }
# float twoab = 2.0 * a * b;
# a = aa - bb + x; // this operation corresponds to z -> z^2+c where z=a+ib c=(x,y)
# b = twoab + y;
# n++;
# absOld = abs;
# }
#
# // We color each pixel based on how long it takes to get to infinity
# // If we never got there, let's pick the color black
# if (n == maxiterations) {
# pixels[i+j*width] = color(0);
# } else {
# // Gosh, we could make fancy colors here if we wanted
# float norm = map(convergeNumber, 0, maxiterations, 0, 1);
# pixels[i+j*width] = color(map(sqrt(norm), 0, 1, 0, 255));
# }
# x += dx;
# }
# y += dy;
# }
# updatePixels();
def settings
full_screen
end
# Establish a range of values on the complex plane
# A different range will allow us to "zoom" in or out on the fractal
def setup
sketch_title 'Mandelbrot Set'
no_loop
# It all starts with the width, try higher or lower values
@w = 4.0
@h = ((@w * height) / width).to_f
# Start at negative half the width and height
@xmin = (-@w / 2.0)
@ymin = (-@h / 2.0)
# x goes from xmin to xmax
# y goes from ymin to ymax
@xmax = @xmin + @w
@ymax = @ymin + @h
# Calculate amount we increment x,y for each pixel
@dx = ((@xmax - @xmin) / width).to_f
@dy = ((@ymax - @ymin) / height).to_f
# Maximum number of iterations for each point on the complex plane
@maxiterations = 100
# Make sure we can write to the pixels[] array.
# Only need to do this once since we don't do any other drawing.
load_pixels
end
def draw
# Start y
y = @ymin.to_f
for j in (0...height) do
# Start x
x = @xmin.to_f
for i in (0...width) do
a = x
b = y
n = 0
max = 4.0 # Infinity in our finite world is simple, just consider it 4
z_old = 0.0
converge_num = @maxiterations # his will change if the while loop breaks due to non-convergence
# Now we test, as we iterate z = z^2 + c does z tend towards infinity?
while n < @maxiterations do
# We suppose z = a+ib
aa = (a * a).to_f
bb = (b * b).to_f
z = sqrt(aa + bb).abs # |z| = sqrt(a^2+b^2)
# Now measure how much we exceeded the maximum
if z > max
diff_to_last = (z - z_old).to_f
diff_to_max = (max - z_old).to_f
converge_num = (n + (diff_to_max / diff_to_last))
break
end
two_ab = (2.0 * a * b)
# this operation corresponds to z -> z^2+c where z=a+ib c=(x,y)
a = (aa - bb + x)
b = (two_ab + y)
n += 1
z_old = z
end
# We color each pixel based on how long it takes to get to infinity.
# If we never got there, pick the color black.
if n == @maxiterations
pixels[i + j * width] = color(0)
else
# Gosh, we could make fancy colors here if we wanted
norm = map1d(converge_num, (0..@maxiterations), (0..1))
pixels[i + j * width] = color(
map1d(sqrt(norm), (0..1), (0..255))
)
end
x += @dx
end
y += @dy
end
update_pixels
end
@dbongo
Copy link
Author

dbongo commented Dec 12, 2020

Screen Shot 2020-12-12 at 4 59 17 PM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment