読者です 読者をやめる 読者になる 読者になる

Arantium Maestum

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

Quil覚書 Clojureで視覚的デザイン

昔からProcessingがやりたかったのだけど、なかなかいい機会がなく放置していた。

しかし、ClojureでもProcessingをベースにしたQuilというライブラリがあることを知り、どうせClojureを勉強しているのだから、と早速使ってみた。

基本中の基本だとこんな感じ。

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

(defn draw []
  (q/rect 0 0 10 10))

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

表示される画像がこれ:

f:id:zehnpaard:20160515153022p:plain

なんとなく、やってることの割にはコードが多くてあまりいい印象じゃない。パワポでやった方が早いし・・・

しかし、コードでやることですぐあらわれるメリットとしては、要素を定義していってドンドン組み合わせていけること。

というわけでdraw関数の中身をboxという別の関数に定義して、drawの中でboxを複数回呼び出してみる。translate関数で画像が描かれる位置がずれるとのこと。

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

(defn box []
  (q/rect 0 0 10 10))

(defn draw []
  (doseq [i (range 3)]
    (q/translate (* i 10) 5)
    (box)))

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

結果がこれ:

f:id:zehnpaard:20160515152843p:plain

期待していたものと違う。(本当は横並びの三つの箱を期待していた)

昔のturtle graphicsのように、ペン先が戻らない仕様らしい。いちいちtranslateで戻すかなー面倒だなーと思って調べていたところ、push-matrixとpop-matrixというよくわからない名称の関数があり、このような画像に対するtransformationをローカル化できるようだ。

ついでにこの「箱三つ並び」という図形も関数化しておく。

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

(defn box []
  (q/rect 0 0 10 10))

(defn line-of-boxes [n]
  (doseq [i (range n)]
    (q/push-matrix)
    (q/translate (* i 10) 5)
    (box)
    (q/pop-matrix)))

(defn draw []
  (line-of-boxes 3))

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

これでいい感じ:

f:id:zehnpaard:20160515153333p:plain

あとはこれらを組み合わせていったり回したり色をつけたり。

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

(defn box []
  (q/rect 0 0 10 10))

(defn line-of-boxes [n]
  (doseq [i (range n)]
    (q/push-matrix)
    (q/translate (* i 10) 5)
    (q/fill (* 255 (/ (- n i) n)) 
            (* 255 (/ i n)) 
            (* 255 (/ i n)) 
            50)
    (box)
    (q/pop-matrix)))

(defn draw []
  (q/translate 50 50)
  (doseq [i (range 12)]
    (q/rotate (Math/toRadians 30))
    (line-of-boxes 3)))
  
(q/defsketch example
  :setup setup
  :size [100 100]
  :draw draw)

だんだんそれっぽくなってくる。

f:id:zehnpaard:20160515154838p:plain

あとは、色のグラディアントを別に定義して、作った図形とうまく組み合わせるような、そういうプログラム構造はできないものか。かなり遊びがいがありそうである。