Ruby でマンデルブロ集合を描画

qiita.comQiita 記事を見てやってみたくなりました。ほとんどパクリです。Numo::NArray を使っています。


実行結果。
20190608211301
 
コード。
mandelbrot_narray.rb

require 'numo/narray'
require 'gdk_pixbuf2'
include Numo

MaxCalc = 5000      #最大計算回数(数字が大きいと細部がくっきりします)
W, H = 1000, 800    #画像サイズ

#計算(size_w: 横幅の長さ, x: 画像中心のx座標, y: 画像中心のy座標)
def mandel(size_w, x, y)
  size_h = size_w * H / W
  c = (DComplex.new(1, W).seq / W * size_w - size_w / 2 + x) +
      (DComplex.new(H, 1).seq / H * size_h - size_h / 2 - y) * Complex(0, 1)

  z = DComplex.new(H, W).fill(0)
  count = Int32.zeros(W, H)
  idx = Int32.new(W, H).seq

  (1..MaxCalc).each do |i|
    z = z ** 2 + c
    idx_t = (z.abs >  2).where
    idx_f = (z.abs <= 2).where
    count[idx[idx_t]] = i
    break if idx_f.empty?

    idx = idx[idx_f]
    z = z[idx_f]
    c = c[idx_f]
  end
  count
end

#データ生成
data0 = mandel(0.004, 0.3801718623708117, 0.19031789808145916)

#画像化
data = UInt8.zeros(W, H, 3)
data[true, true, 1] = (data0 % 255 - 127).abs * 2    #着色

pixbuf = GdkPixbuf::Pixbuf.new(data: data.to_string, width: W, height: H)

pixbuf.save('mandel.png')

 
いちばん基本的なマンデルブロ集合は mandel(4.0, 0.0, 0.0) という感じで生成します。
20190608121156
色の付け方をあれこれ工夫したいところですね。

こんなのも。mandel(0.004, 0.30145277714203783, 0.024192503140736933) でやってみた。
20190608212923

 
※参考
Numo::NArray概要 · ruby-numo/numo-narray Wiki · GitHub
NArrayの簡単なつかい方 - Qiita
マンデルブロ集合の不思議な世界
 
※追記
よく考えたらこれでは上下が逆転するので、コードを修正しました。上の画像はすべて上下が反転しています。


追加。mandel(0.004, 0.282, -0.01)
20190608221942