Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Standard Widget Toolkit (SWT) » Mandelbrot Fractal with Glimmer DSL for SWT(Implemented Mandelbrot Set Fractal, Parallelized with all CPU cores, and then rendered with Glimmer DSL for SWT)
Mandelbrot Fractal with Glimmer DSL for SWT [message #1838391] Wed, 24 February 2021 02:46
Andy Maleh is currently offline Andy MalehFriend
Messages: 75
Registered: March 2020
Location: Montreal, Quebec, Canada
Member
For the hardcore Computer Scientists out there who have strong interest in graphical algorithms, the Mandelbrot Set is a very well known Computer Science/Math algorithm that renders a fractal at various zoom levels, demonstrating the repetitive nature of fractals. During my bachelor of Computer Science at McGill University (Montreal, QC, Canada), I remember spending very long and tiring nights at the computer lab to implement an Assembly language renderer of the Mandelbrot Fractal. Much has changed since then. We have multi-core processors today, let alone the wonderful Ruby programming language, so I wrote this with Glimmer DSL for SWT by taking advantage of the multi-threaded JRuby and saturating all CPU cores to finish calculating Mandelbrot points in less than 10 seconds on 4 CPU cores. The sample supports unlimited zooming, pre-calculated in the background with the window title bar notifying you once higher zooms are available. It also allows panning with scrollbars or mouse dragging.

https://lh3.googleusercontent.com/-1aOMtrXxN1w/YCvdpNoHeAI/AAAAAAAABmY/R6kATvUyz7QSYrNugPsV4bkzJLQB03-FwCLcBGAsYHQ/glimmer-mandelbrot-zoom1.png

Below is the multi-threaded model code and Glimmer GUI DSL code of the Mandelbrot Fractal initial version (without zooming or menus). The Glimmer DSL for SWT GUI simply paints an image as a form of image buffering (to avoid Mandelbrot pixel repaints on GUI repaints) and then puts it inside a canvas to display.

require 'glimmer-dsl-swt'
require 'complex'
require 'concurrent-ruby'

class Mandelbrot
  attr_accessor :max_iterations

  def initialize(max_iterations)
    @max_iterations = max_iterations
  end
  
  def calculate_all(x_array, y_array)
    thread_pool = Concurrent::FixedThreadPool.new(Concurrent.processor_count)
    width = x_array.size
    height = y_array.size
    pixel_rows_array = Concurrent::Array.new(height)
    height.times do |y|
      pixel_rows_array[y] ||= Concurrent::Array.new(width)
      width.times do |x|
        thread_pool.post do
          pixel_rows_array[y][x] = calculate(x_array[x], y_array[y]).last
        end
      end
    end
    thread_pool.shutdown
    thread_pool.wait_for_termination
    pixel_rows_array
  end

  # Mandelbrot point calculation implementation
  # Courtesy of open-source code at:
  # https://github.com/gotbadger/ruby-mandelbrot
  def calculate(x,y)
    base_case = [Complex(x,y), 0]
    Array.new(max_iterations, base_case).inject(base_case) do |prev ,base|
      z, itr = prev
      c, _ = base
      val = z*z + c
      itr += 1 unless val.abs < 2
      [val, itr]
    end
  end
end

class MandelbrotFractal
  include Glimmer::UI::CustomShell
  
  before_body {
    @colors = [[0, 0, 0]] + 40.times.map { |i| [255 - i*5, 255 - i*5, 55 + i*5] }
    @colors = @colors.map {|color_data| rgb(*color_data).swt_color}
    mandelbrot = Mandelbrot.new(@colors.size - 1)
    @y_array = (1.0).step(-1,-0.0030).to_a
    @x_array = (-2.0).step(0.5,0.0030).to_a
    @height = @y_array.size
    @width = @x_array.size
    @pixel_rows_array = mandelbrot.calculate_all(@x_array, @y_array)
    @image = Image.new(display.swt_display, @width, @height)
    image_gc = org.eclipse.swt.graphics.GC.new(@image)
    @height.times { |y|
      @width.times { |x|
        new_foreground = @colors[@pixel_rows_array[y][x]]
        image_gc.foreground = @current_foreground = new_foreground unless new_foreground == @current_foreground
        image_gc.draw_point x, y
      }
    }
  }

  body {
    shell {
      text 'Mandelbrot Fractal'
      minimum_size @width, @height + 12
      image @image
      
      canvas {
        image(@image, 0, 0)
      }
    }
  }
end

MandelbrotFractal.launch


Learn more at this blog post:
https://andymaleh.blogspot.com/2021/02/glimmer-dsl-for-swt-mandelbrot-fractal.html

Enjoy!


EclipseCon / EclipseWorld / Agile Conference Speaker
Open-Source Software Author of Glimmer DSL for SWT

[Updated on: Wed, 24 February 2021 03:23]

Report message to a moderator

Previous Topic:Display.syncExec in Threads is HISTORY in Glimmer DSL for SWT!!!
Next Topic:Metronome app built in under 10 minutes with Glimmer DSL for SWT
Goto Forum:
  


Current Time: Fri Apr 26 11:19:15 GMT 2024

Powered by FUDForum. Page generated in 0.03547 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top