Parameter = Struct.new(:cx, :cy, :ch, :cw) # required for future RATIO = 1.336 TMAX = 5_000 attr_reader :current, :default # required for future work def setup size(534, 400, P2D) @default = Parameter.new(-0.53 - (1.4 * RATIO), -1.4, 2.8, 2.8 * RATIO) @current = default load_pixels no_fill stroke(255) create_mandelbrot(width, height) no_loop end def create_mandelbrot(w, h) y_zero = ->(y, param) { y * param.ch / height + param.cy } x_zero = ->(x, param) { x * param.cw / width + param.cx } h.times do |j| y0 = y_zero.call(j, current) w.times do |k| x0 = x_zero.call(k, current) x, y = 0, 0 xsqr, ysqr = 0.0, 0.0 t = 0 while t < TMAX && (xsqr + ysqr < 4.0) y = x * y y += y + y0 x = xsqr - ysqr + x0 xsqr = x * x ysqr = y * y t += 1 end if t < TMAX smth = t - Math.log(xsqr + ysqr) pixels[k + j * width] = Java::JavaAwt::Color.HSBtoRGB(smth / 500, 0.8, 0.9) else pixels[k + j * width] = 0 end end end update_pixels end
Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0
Showing posts with label mandelbrot. Show all posts
Showing posts with label mandelbrot. Show all posts
Thursday, 25 December 2014
Towards a zoom-able mandelbrot ruby-processing
Working toward a zoom-able mandelbrot (albeit somewhat speed limited in ruby-processing)
Labels:
mandelbrot,
ruby-processing
Thursday, 14 August 2014
Experimental map1d method JRubyArt (ruby-processing development)
The recently updated JRubyArt has now removed the processing convenience functions that were deprecated in ruby-processing-2.5.1. Other functions such as map are retained, but I wondered would a map1d range method be a more ruby like alternative:-
PS: I have not tested whether Jordans findings re: ruby complex implementation still hold true (jruby truffle claims wicked fast mandelbrot calculations). Benchmarking is tricky with jvm warmup up time, I have replaced sqrt(real * real + imag * imag) (abs method) with hypot(real, imag), which should be more efficient...
# @param [float] val # @param [range(start1 .. end1)] r_in # @param [range(start2 .. end2)] r_out # @return [float] mapped value # def map1d(val, r_in, r_out) r_out.first + (r_out.last - r_out.first) * ((val - r_in.first).to_f / (r_in.last - r_in.first)) end # usage map1d(5, (0 .. 10), (10 .. 110)) exclude end is false puts map1d(5, (0 .. 10), (10 .. 110)) # output 60.0Here is the method in action
# Mandelbrot Set example # by Jordan Scales (http://jordanscales.com) # 27 Dec 2012 # Modified to use map1d (instead of map), and somewhat # optimized (update_pixels instead of set, and hypot for abs) # default size 900x600 # no need to loop def setup size 900, 600 load_pixels no_loop end # main drawing method def draw (0 ... 900).each do |x| (0 ... 600).each do |y| c = Complex.new(map1d(x, (0 .. 900), (-3 .. 1.5)), map1d(y, (0 .. 600), (-1.5 .. 1.5))) # mandel will return 0 to 20 (20 is strong) # map this to 0, 255 (and flip it) pixels[x + y * 900] = color(255 - map1d(mandel(c, 20), (0 .. 20), (0 .. 255)).to_i) end end update_pixels end # calculates the "accuracy" of a given point in the mandelbrot set # : how many iterations the number survives without becoming chaotic def mandel(z, max = 10) score = 0 c = z.clone while score < max # z = z^2 + c z.square z.add c break if z.abs > 2 score += 1 end score end # rolled my own Complex class # stripped of all functionality, except for what I needed (abs, square, add, to_s) # # Using this class, runs in ~12.5s on my MacBook Air # compared to ~22s using ruby's Complex struct class Complex attr_accessor :real, :imag def initialize(real, imag) @real = real @imag = imag end # square a complex number - overwriting it def square r = real * real - imag * imag i = 2 * real * imag @real = r @imag = i end # add a given complex number def add(c) @real += c.real @imag += c.imag end # compute the magnitude def abs hypot(real, imag) end def to_s "#{real} + #{imag}i" end end
PS: I have not tested whether Jordans findings re: ruby complex implementation still hold true (jruby truffle claims wicked fast mandelbrot calculations). Benchmarking is tricky with jvm warmup up time, I have replaced sqrt(real * real + imag * imag) (abs method) with hypot(real, imag), which should be more efficient...
Labels:
JRubyArt,
mandelbrot,
map,
map1d
Subscribe to:
Posts (Atom)
Followers
About Me
- monkstone
- I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2

