Arantium Maestum

プログラミング、囲碁、読書の話題

Quilでフラクタル Koch

積読中だった「関数型オブジェクト指向AIプログラミング」フラクタルの話が出ていたのを思い出したのでQuilでやってみる。

ちなみにこの本はScalaで、フラクタルに関して出てくるコードはどこをどう見ても相当オブジェクト指向なのが少し不思議。パッと見た限りあまり好みのコードではないが・・・

とりあえずclojure+Quilに書き直してみる。

まずは、描線関数。角度をラジアンでとるのと、次の起点が今描いた線の先にあるのがポイント。

(ns koch-fractal
  (:require [quil.core :as q]))

(defn forward [len angle]
  (let [x (* len (Math/cos angle))
        y (* len (Math/sin angle))]
    (q/line 0 0 x y)
    (q/translate x y)))

再帰的に定義されたkoch関数。画像を出力するプログラムで再帰を見ると、思わず「おっ、フラクタルゥー」となるのでよろしいかと。

(defn koch [n len angle]
  (if (= 1 n)
    (forward len angle)
    (let [l  (/ len (+ 2 (/ 2 (Math/sqrt 2))))
          a  (* Math/PI 0.25)]
      (doall
        (map #(koch (dec n) l %)
          [angle (- angle a) (+ angle a) angle])))))

あとはまあ描くだけ。drawにはなるべく仕事をさせないようにすると、作った図形が再利用しやすい。

(defn draw []
  (q/translate 50 100)
  (koch 4 100 0))

(defn setup []
  (q/background 255))

(q/defsketch example
  :setup setup
  :draw draw
  :size [200 200])

結果;

f:id:zehnpaard:20160516043904p:plain