ContextFreeArtとNodeBox

Context Free Art - 西尾泰和のはてなダイアリーで書いたものをNodeBoxでも書いてみた。

def circle():
    oval(0, 0, 1, 1)

scale(200)
translate(1, 1)

def egg(level=0):
    if level == 8: return
    circle()

    push()
    fill(1, 1, 1)
    scale(0.9)
    circle()
    fill(0, 0, 0)
    pop()

    push()
    translate(0.3, 0)
    scale(0.6)
    rotate(10)
    egg(level + 1)
    pop()

    push()
    translate(-0.3, 0)
    scale(0.6)
    rotate(10)
    egg(level + 1)
    pop()

egg()

Context Free Artは教育用途にむいているか? - 西尾泰和のはてなダイアリーで書いたように「再起呼び出しの終了条件」「回転、スケール、色などのコンテキストのpushとpop」が明示的に追加されています。


あと、絵を見るとわかるのですけどオリジナルと違って腕の一部が隠れてますね。素朴に再起呼び出しで書いてしまうと深さ優先、つまりまず右の腕を全部かいてから左の腕をかき始めるのですが、ContextFreeArtでは再起呼び出しのその場で描画せずに「どこに何を描くべき」という情報をためておいて最後にまとめて呼び出しの浅い順に描いています。これが「直接カンバスに描きながら再起呼び出しをするだけではなく、Zオーダーでソートしてから描き直す処理を自動でやってくれる」という長所。これを実装しようと思うと、「現在のどういうスケール、回転、平行移動になっているか」の情報を取得して保存しておくことが必要になるわけですが…NodeBoxのヘルプを軽く眺めただけではそういう関数が見つかりませんでした。それがあれば再起の終了条件も「スケールが一定以下だったら」という切り方にしたりできるはず。


TODO: 気がむいたらInkscapeとProcessingでも同じものを描く。