@uents blog

Code wins arguments.

SICP 読書ノート#12 - 2.2.4 図形言語(2) (pp.73-83)

Racket Graphics Legacy Libraryを使う

前回のplanet/sicp.ssではほとんど実装済みであまり勉強にならないので、Graphics Legacy Libraryがおすすめ。

ただ直線などのプリミティブな描画はできるが、画像の扱い方はよくわからない。

画像をキャンバスへ直接描画することはできるけど、pixmapデータとして持つ手段はなさそう。 image->painterみたいな手続きを作りたいんだけどな… 頑張るならPGMデータを直接ロードしてsegment化とかかな。

キャンバスをオープン

白いキャンバスウィンドウが表示される。

(require (prefix-in gfx: graphics/graphics))
(gfx:open-graphics)
(define vp (gfx:open-viewport "A Picture Language" 500 500))

image

直線を描画

直線を引く。原点は画面左上らしい。

((gfx:draw-line vp) (make-posn 100 400) (make-posn 400 100))

image

キャンバスをクリア

キャンバスの内容をクリアする。

((gfx:clear-viewport vp))

キャンバスをクローズ

ビューポイントおよびウィンドウをクローズする。

(gfx:close-viewport vp)
(gfx:close-graphics)

ツールっぽくする

毎回上記のコマンドを入力するのも面倒なので、

#lang racket

(require (prefix-in gfx: graphics/graphics))

(define canvas-margin 4)
(define canvas-width  512)
(define canvas-height 512)

(define vp nil) ;; view point

(define open-canvas
  (lambda ()
    (if (null? vp)
        (begin
          (gfx:open-graphics)
          (set! vp (gfx:open-viewport
                    "A Picture Language"
                    (+ canvas-width  (* canvas-margin 2))
                    (+ canvas-height (* canvas-margin 2)))))
        nil)))

(define close-canvas
  (lambda ()
    (if (null? vp)
        nil
        (begin
          (gfx:close-viewport vp)
          (gfx:close-graphics)
          (set! vp nil)))))

(define clear-canvas
  (lambda ()
    (if (null? vp)
        nil
        ((gfx:clear-viewport vp)))))


(provide (all-defined-out))

みたいなのをファイルcanvas.scmを作成しておいて、

racket@> (require "canvas.scm")
racket@> (open-canvas)
racket@> ((gfx:draw-line vp) (make-posn 50 50) (make-posn 450 450))

で、キャンバスをオープンして直線が引ける。

racket@> (clear-canvas)

で、キャンバスの消去、

racket@> (close-canvas)

で、キャンバスをクローズする。

次回はこれを使って「§2.2.4 図形言語」の練習問題へ。


※「SICP読書ノート」の目次はこちら