circleの範囲を最適化

バッファ上で円を塗りつぶすとき、

  (0...buf.y).each do |i|
    (0...buf.x).each do |j|
      if (y - i)**2 + (x -j)**2 < r**2 then
        buf.buf[i][j] = color
      end
    end
  end

とやっていたけど、明らかにチェックする意味がないところまで調べているので、

  upper = (y - r) > 0 ? (y - r) : 0
  lower = (y + r) > buf.y ? buf.y : (y + r)
  left = (x - r) > 0 ? (x - r) : 0
  right = (x + r) > buf.x ? buf.x : (x + r)

  (upper...lower).each do |i|
    (left...right).each do |j|
      if test.within_circle(x, y, i, j, r) > 0 then 
        buf.buf[i][j] = color
      end
    end
  end

と書き換えた。結局、もとのコードと比較するとCにしたことで1.5倍ぐらい、上記のチェック範囲の限定で1.8倍ほど高速化した。100個の円を描くのに9.5秒ほどかかっていたものが3.3秒ぐらいになった。実際にはバッファの初期化や画像のロードに1秒ほどかかっているので、100個の円は2秒ちょい。

ということは100個の円を進化させるのに1サイクルで最低4秒ぐらい。画像の比較は相当に重たい処理のはずだから、うーん、やっぱりちょっと厳しいかも。うまくやれば変化した部分だけの比較にできて、それなら10分ぐらいで何らかの進化もさせられそうな気がするけど。これはやっぱりCとかJavaの仕事なんだろうな。