Created
January 10, 2010 17:43
-
-
Save dwaite/273634 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' | |
BENCHMARK_REPS = ARGV[0] ? ARGV[0].to_i : 1 | |
WIDTH,HEIGHT = 640,480 | |
MAX_COLOR = 360 | |
ZOOM_FACT = 0.8 | |
MAX_ITERATIONS = 40 | |
CENTER = -0.65 | |
X_INC = WIDTH / (200000 * ZOOM_FACT) | |
Y_INC = HEIGHT / (150000 * ZOOM_FACT) | |
SAT = 0.85 | |
VAL = 0.85 | |
class HSV | |
def initialize h, s, v | |
@h,@s,@v = h,s,v | |
end | |
def hi | |
(@h / 60).floor % 6 | |
end | |
def f | |
@h / 60 - hi | |
end | |
def p | |
(1 - @s) * @v | |
end | |
def q | |
(1 - f * @s) * @v | |
end | |
def t | |
(1 - ((1 - f) * @s)) * @v | |
end | |
def to_rgb | |
h = hi | |
case h | |
when 0 | |
[@v, t, p] | |
when 1 | |
[q, @v, p] | |
when 2 | |
[p, @v, t] | |
when 3 | |
[p, q, @v] | |
when 4 | |
[t, p ,@v] | |
else | |
[@v, p, q] | |
end | |
end | |
end | |
def scale x | |
return (x * 255).to_i | |
end | |
def scale_rgb rgb | |
[scale(rgb[0]),scale(rgb[1]),scale(rgb[2])] | |
end | |
def make_color_map nb_cols | |
out = [] | |
nb_cols.times do |i| | |
hsv = HSV.new((360.0 * i) / (nb_cols + 1), SAT, VAL) | |
color = scale_rgb hsv.to_rgb | |
out << ('' << color[0] << color[1] << color[2]) | |
end | |
out | |
end | |
COLOR_MAP = make_color_map [MAX_ITERATIONS,MAX_COLOR].min | |
def c i,j | |
Complex(X_INC * i + CENTER - X_INC * WIDTH / 2, Y_INC * j - Y_INC * HEIGHT / 2) | |
end | |
class Complex | |
def absq | |
real*real + image*image | |
end | |
end | |
def pixel c | |
z = Complex(0) | |
i = MAX_ITERATIONS | |
while i > -1 do | |
z = z*z + c | |
if z.absq >= 4.0 | |
return i | |
end | |
i -= 1 | |
end | |
return nil | |
end | |
def color iterations | |
if iterations != nil | |
COLOR_MAP[iterations % COLOR_MAP.length] | |
else | |
return "\0\0\0" | |
end | |
end | |
def render | |
output = '' | |
HEIGHT.times do |j| | |
WIDTH.times do |i| | |
output << (color pixel(c i,j)) | |
end | |
end | |
output | |
end | |
def ppm_header | |
"P6\n#{WIDTH} #{HEIGHT}\n255\n" | |
end | |
BENCHMARK_REPS.times do | |
File.open("mandelbrot.ppm", "w") do |f| | |
f.write ppm_header | |
f.write render | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment