Last active
May 25, 2019 09:43
-
-
Save JoshCheek/f1d044067cd37ae774b4cb1989b0bf16 to your computer and use it in GitHub Desktop.
Tweetable Mandelbrot Set
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# The first version was one I made in 2017 for Graphics, | |
# it has much better resolution but isn't animated: | |
# https://twitter.com/josh_cheek/status/846199094519443456 | |
# https://gist.github.com/JoshCheek/dbb07c35e46d45f57c33579e03095f1c |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'graphics' | |
# https://www.bowdoin.edu/~dfrancis/askanerd/mandelbrot/ | |
# | |
# Consider the code: | |
# Z = 0 | |
# C = /* some complex number */ | |
# loop { Z = Z*Z + C } | |
# | |
# The Mandelbrot Set is the set of every C | |
# where Z doesn't grow beyond the number 2. | |
# | |
# This is done by sampling values for C and iterating up to a horizon. | |
# The colours are applied to the values outside the Mandelbrot Set | |
# based on how many iterations it took them to grow beyond 2. | |
def mandelbrot(x, y, iterations) | |
c,z=x+y*1i,0 | |
iterations.times.find do |i| | |
z = z*z+c | |
2<z.magnitude | |
end | |
end | |
require 'io/console' | |
h, w = $stdin.winsize | |
# x_target = -0.7453 | |
# y_target = 0.1127 | |
# x_target = -1.0396344968890008 | |
# y_target = 0.3588067730189076 | |
x_target = -1.0051487086372168 | |
y_target = 0.29104801319928053 | |
xr = w/4.0 | |
yr = h/2.0 | |
num_samples = 20 | |
loop do | |
xs = x_target - xr | |
ys = y_target - yr | |
xf = x_target + xr | |
yf = y_target + yr | |
crnt_width = (xf-xs) | |
crnt_height = (yf-ys) | |
$><< "\e[H"+h.times.map do |v| | |
w.times.map do |u| | |
x = xs+crnt_width*u/w | |
y = ys+crnt_height*v/h.to_f | |
depth = mandelbrot(x, y, num_samples) || 0 | |
"\e[48;2;#{(255*depth/num_samples/2).to_i};0;0m " | |
end*"" | |
end*"\n" | |
xr *= 0.9 | |
yr *= 0.9 | |
num_samples += 1 | |
# print "\e[H" + {x:x_target,y:y_target,xr:xr,yr:yr}.inspect | |
# char = $stdin.raw { $stdin.readpartial 100 } | |
# case char | |
# when ?\C-c | |
# break | |
# when ?h then x_target -= xr/20 | |
# when ?l then x_target += xr/20 | |
# when ?j then y_target += yr/20 | |
# when ?k then y_target -= yr/20 | |
# end | |
end | |
# @initial_width = 5 | |
# @initial_height = 2 | |
# @target = [w/2, h/2] | |
# @center = [0, 0] | |
# mb = MandelBrot.new w, h | |
# depth = 3 | |
# mandelbrot_width = @initial_width / depth.to_f | |
# mandelbrot_height = @initial_height / depth.to_f | |
# mid_x, mid_y = @center | |
# start_x = mid_x - mandelbrot_width / 2 | |
# start_y = mid_x - mandelbrot_height / 2 | |
# end_x = start_x + 0.04 / depth * 100 | |
# end_y = start_y + 0.03 / depth * 100 | |
# ∆x = end_x - start_x | |
# ∆y = end_y - start_y | |
# colors = [:red, :green, :blue, :cyan, :magenta, :yellow] | |
# x_step = ∆x / w | |
# y_step = ∆y / h | |
# pixel_width = 0.5 | |
# pixel_height = 1 | |
# x_iterations = (w/pixel_width).ceil | |
# y_iterations = (h/pixel_height).ceil | |
# h.times do |y| | |
# initial_y = y * ∆y / w + start_y | |
# w.times do |x| | |
# initial_x = x * ∆x / y + start_x | |
# n = if depth = mandelbrot(y/h.to_f, x/w.to_f, 20) | |
# depth*255/20 | |
# else | |
# 0 | |
# end | |
# print "\e[#{y+1};#{h+1}H\e[48;2;#{depth};0;0m " | |
# end | |
# end | |
# x_iterations.times do |x| | |
# initial_x = x * ∆x / x_iterations + start_x | |
# y_iterations.ceil.times do |y| | |
# initial_y = y * ∆y / y_iterations + start_y | |
# # mb.rect x*pixel_width, y*pixel_width, pixel_width, pixel_height, color, :fill | |
# mb.point x*pixel_width, y*pixel_width, color | |
# end | |
# end | |
# # NOTE ON ZOOMING: It should zoom such that the target is in the same location | |
# # on the screen after the zoom as it was before the zoom | |
# mb.run |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def mandelbrot(x, y, iterations) | |
c,z=x+y*1i,0 | |
iterations.times.find do |i| | |
z = z*z+c | |
2<z.magnitude | |
end | |
end | |
require 'io/console' | |
h, w = $stdin.winsize | |
x_target=-1.0051487086372168 | |
y_target=0.29104801319928053 | |
xr=w/4.0 | |
yr=h/2.0 | |
num_samples = 20 | |
loop do | |
xs = x_target - xr | |
ys = y_target - yr | |
xf = x_target + xr | |
yf = y_target + yr | |
crnt_width = (xf-xs) | |
crnt_height = (yf-ys) | |
$><< "\e[H"+h.times.map do |v| | |
w.times.map do |u| | |
x = xs+crnt_width*u/w | |
y = ys+crnt_height*v/h.to_f | |
depth = mandelbrot(x, y, num_samples) || 0 | |
"\e[48;2;#{(255*depth/num_samples/2).to_i};0;0m " | |
end*"" | |
end*"\n" | |
xr *= 0.9 | |
yr *= 0.9 | |
num_samples += 1 | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'io/console' | |
h,w = $stdin.winsize | |
x_target=-1.0051487086372168 | |
y_target=0.29104801319928053 | |
xr=w/4.0 | |
yr=h/2.0 | |
num_samples = 20 | |
loop do | |
xs = x_target - xr | |
ys = y_target - yr | |
xf = x_target + xr | |
yf = y_target + yr | |
crnt_width = (xf-xs) | |
crnt_height = (yf-ys) | |
$><< "\e[H"+h.times.map do |v| | |
w.times.map do |u| | |
x = xs+crnt_width*u/w | |
y = ys+crnt_height*v/h | |
c,z=x+y*1i,0 | |
depth = num_samples.times.find do |i| | |
z = z*z+c | |
2<z.magnitude | |
end || 0 | |
"\e[48;2;#{(255*depth/num_samples/2).to_i};0;0m " | |
end*"" | |
end*"\n" | |
xr*=0.9 | |
yr*=0.9 | |
num_samples += 1 | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'io/console' | |
h,w = $stdin.winsize | |
xt=-1.0051487086372168 | |
yt=0.29104801319928053 | |
xr=w/4.0 | |
yr=h/2.0 | |
n = 20 | |
loop{ | |
xs=xt-xr | |
ys=yt-yr | |
xf=xt+xr | |
yf=yt+yr | |
crnt_width = (xf-xs) | |
crnt_height = (yf-ys) | |
$><< "\e[H"+h.times.map do |v| | |
w.times.map do |u| | |
x = xs+crnt_width*u/w | |
y = ys+crnt_height*v/h | |
c,z=x+y*1i,0 | |
depth = n.times.find do |i| | |
z = z*z+c | |
2<z.magnitude | |
end || 0 | |
"\e[48;2;#{(255*depth/n/2).to_i};0;0m " | |
end*"" | |
end*"\n" | |
xr*=0.9 | |
yr*=0.9 | |
n += 1 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'io/console' | |
h,w = $stdin.winsize | |
xt=-1.0051487086372168 | |
yt=0.29104801319928053 | |
xr=w/4.0/9 | |
yr=h/2.0/9 | |
n=10 | |
loop{ | |
crnt_width = 2*xr | |
crnt_height = 2*yr | |
$><< "\e[H"+h.times.map do |v| | |
w.times.map do |u| | |
x = (xt-xr)+crnt_width*u/w | |
y = (yt-yr)+crnt_height*v/h | |
c,z=x+y*1i,0 | |
depth = n.to_i.times.find do |i| | |
z = z*z+c | |
2<z.magnitude | |
end || 0 | |
"\e[48;5;#{232+(24*depth/n).to_i}m " | |
end*"" | |
end*"\n" | |
xr*=0.9 | |
yr*=0.9 | |
n += 0.5 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'io/console' | |
h,w = $stdin.winsize | |
xt=-1.0051487086372168 | |
yt=0.29104801319928053 | |
xr=w/4.0/9 | |
yr=h/2.0/9 | |
n=10 | |
loop{ | |
crnt_width = 2*xr | |
crnt_height = 2*yr | |
$><< "\e[H"+h.times.map do |v| | |
w.times.map do |u| | |
x = (xt-xr)+crnt_width*u/w | |
y = (yt-yr)+crnt_height*v/h | |
c,z=x+y*1i,0 | |
depth = n.to_i.times.find do |i| | |
z = z*z+c | |
2<z.magnitude | |
end || 0 | |
"\e[48;5;#{232+(24*depth/n).to_i}m " | |
end*"" | |
end*"\n" | |
xr*=0.9 | |
yr*=0.9 | |
n += 0.5 | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ruby -e h,w=$LINES,$COLUMNS' | |
xt=-1.0051487086372168 | |
yt=0.29104801319928053 | |
xr=w/18.0 | |
yr=h/9.0 | |
n=10 | |
loop{ | |
$><<"\e[H"+h.times.map{|v| | |
w.times.map{|u| | |
x=(xt-xr)+2*xr*u/w | |
y=(yt-yr)+2*yr*v/h | |
c,z=x+y*1i,0 | |
depth = n.to_i.times.find{|i| | |
z=z*z+c | |
2<z.magnitude | |
}||0 | |
"\e[48;5;#{232+(24*depth/n).to_i}m " | |
}*"" | |
}*?\n | |
xr*=0.9 | |
yr*=0.9 | |
n += 0.6 | |
}' | |
# 13 away | |
ruby -e h,w=$LINES,$COLUMNS' | |
a=w/18.0 | |
b=h/9.0 | |
n=10 | |
loop{$><<"\e[H"+h.times. map{|v|w.times. map{|u| | |
x=(-1.0051487086372168-a)+2*a*u/w | |
y=(0.29104801319928053-b)+2*b*v/h | |
c,z=x+y*1i,0 | |
"\e[48;5;#{232+(24*(n. to_i.times.find{|i|z=z*z+c;2<z.magnitude}||0)/n).to_i}m "}*""}*?\n | |
a*=0.9 | |
b*=0.9 | |
n+=0.6}' | |
ruby -eh,w=$LINES,$COLUMNS' | |
a=w/9.0 | |
b=h/4.5 | |
n=9 | |
loop{$><<"\e[H"+h.times.map{|v|w.times.map{|u|c,z=2*a*u/w-1.005148708637216-a+(2*b*v/h+0.291048013199280-b)*1i,0 | |
"\e[48;5;#{(232+24*(n.to_i.times.find{|i|z=z*z+c;2<z.magnitude}||0)/n).to_i}m "}*""}*?\n | |
a*=0.9 | |
b*=0.9 | |
n+=0.6}' | |
# FINAL: | |
ruby -eh,w=$LINES,$COLUMNS' | |
a=w/9.0 | |
b=h/4.5 | |
n=9 | |
loop{$><<"\e[H"+h.times. map{|v|w.times. map{|u|c,z=2*a*u/w-1.005148708637216-a+(2*b*v/h+0.291048013199280-b)*1i,0 | |
"\e[48;5;#{(232+24*(n. to_i.times.find{|i|z=z*z+c;2<z.magnitude}||0)/n).to_i}m "}*""}*?\n | |
a*=0.99 | |
b*=0.99 | |
n+=0.06}' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment