Last active
May 2, 2016 17:40
-
-
Save carlocasorzo/0e22c08c805a8877ffa83c5aae173d02 to your computer and use it in GitHub Desktop.
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 'complex' | |
require 'matrix' | |
require 'chunky_png' | |
module Fractal | |
class Mandelbrot | |
class << self | |
# Returns the mandelbrot value after iterating over c | |
def mandelbrot(c, dim=2) | |
Array.new(100).inject(0) { |z,i| z ** dim + c } | |
end | |
# Returns the color of the mandelbrot value acording to its abs | |
def mandelbrot_color(c, exp, limit=2) | |
abs = mandelbrot(c, exp).abs | |
if abs < limit | |
intensity = (255 * abs / limit).to_i | |
ChunkyPNG::Color.rgba(0, 0, intensity, 255) | |
else | |
ChunkyPNG::Color::WHITE | |
end | |
end | |
# Returns the mandelbrot set matrix | |
def mandelbrot_set(options={}) | |
resolution = options[:resolution] || 1000 | |
x1 = options[:x1] || -2.0 | |
x2 = options[:x2] || 2.0 | |
y1 = options[:y1] || -2.0 | |
y2 = options[:y2] || 2.0 | |
dim = options[:dim] || 2.0 | |
set = Array.new(resolution) { Array.new(resolution) } | |
set.each_with_index do |col, i| | |
col.each_with_index do |value, j| | |
step_x = (x2 - x1) / resolution | |
step_y = (y2 - y1) / resolution | |
z = Complex(x1 + i * step_x, y1 + j * step_y) | |
set[i][j] = mandelbrot_color(z, dim) | |
end | |
end | |
return set | |
end | |
# Creates an png image from a mandelbrot set matrix | |
def create_image(options) | |
image_name = options['image_name'] || 'mandelbrot' | |
set = mandelbrot_set(options) | |
png = ChunkyPNG::Image.new(set.length, set[0].length, ChunkyPNG::Color::BLACK) | |
set.each_with_index do |col, i| | |
col.each_with_index do |value, j| | |
png[i,j] = value | |
end | |
end | |
png.save("#{image_name}.png") | |
end | |
# Creates an sequence of png images from a variable exponent mandelbrot set | |
def generate_sequence(options={}) | |
start = options[:start] || 0 | |
finish = options[:finish] || 10 | |
step = options[:step] || 0.1 | |
counter = 0 | |
(start).step(finish, step) do |dim| | |
options[:dim] = dim | |
dim_to_s = dim.to_s | |
dim_to_s = dim_to_s[0, dim_to_s.index('.') + 2] | |
options['image_name'] = "mandelbrot_#{counter}_#{dim_to_s}" | |
counter += 1 | |
create_image(options) | |
end | |
end | |
end | |
end | |
end | |
## Usage examples | |
# Fractal::Mandelbrot.mandelbrot_set resolution: 100, x1: -2, x2: 2, y1: -1, y2: 1 | |
# Fractal::Mandelbrot.create_image resolution: 100 | |
# Fractal::Mandelbrot.generate_sequence(resolution: 1000, start: -10, finish: 10) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment