奥村さんのアルゴリズム本をSchemeでやるシリーズが滞っていたので進めます。
ちなみにこういう取り組みって権利的にどうなのか微妙だなーと思っていたところ以下のサイトで権利問題がクリアにしてあったのでとりあえず安心しています。
GitHub - okumuralab/algo-c
振り返り
これまでの結果は以下の通りです。
- グラフィックスの下準備 その1 - 仮想計算機構
- グラフィックスの下準備 その2 - 仮想計算機構
- 線を丁寧に描くよ - 仮想計算機構
- 円を丁寧に描くよ - 仮想計算機構
- Schemeでセルラー・オートマトン - 仮想計算機構
- Schemeでカラフルな図形を描く - 仮想計算機構
思えば色々やってきたものですね。下の2つは奥村さんの本とは関係ないですが。
今回の取り組み
今までは640 x 400の画像を作るために、ピクセルを座標に見立ててやっていたわけですが、いろいろ不便です。この問題を解決するのが奥村本p.66 の window.c というプログラムになります。こちらをSchemeで書いてみます。コードは以下の通りです。
;;; window.scm (include "line.scm") (define gr_xfac 1) (define gr_yfac 1) (define gr_xconst 0) (define gr_yconst 0) (define (gr_xscr x) (round->exact (+ (* gr_xfac x) gr_xconst)) ) (define (gr_yscr y) (round->exact (+ (* gr_yfac y) gr_yconst)) ) (define (gr_wdot x y color) (gr_dot (gr_xscr x) (gr_yscr y) color) ) (define (gr_wline x1 y1 x2 y2 color) (gr_line (gr_xscr x1) (gr_yscr y1) (gr_xscr x2) (gr_yscr y2) color) ) (define (gr_window left bottom right top samescale) (set! gr_xfac (/ (- XMAX 1) (- right left))) (set! gr_yfac (/ (- YMAX 1) (- top bottom))) (if samescale (if (> (abs gr_xfac) (abs gr_yfac)) (set! gr_xfac (* gr_xfac (abs (/ gr_yfac gr_xfac)))) (set! gr_yfac (* gr_yfac (abs (/ gr_xfac gr_yfac)))) ) ) (set! gr_xconst (- 0.5 (* gr_xfac left))) (set! gr_yconst (- 0.5 (* gr_yfac bottom))) )
実行結果
早速ためしてみましょう。傾き1の直線を (-2, -2) から (2, 2)の範囲に描きます。
;;; test_window.scm (include "grBMP.scm") (include "window.scm") (gr_window -2 -2 2 2 #f) (gr_wline -1 -1 1 1 WHITE) (gr_BMP "test.bmp")
プログラム実行後に以下のtest.bmpが生成されました。
本来であれば45度の角度になっていないとおかしいのですが、空間が横の方が長いのでそれにあわせて表示されている状態です。
gr_windowの引数を変えると各軸のスケールを同じにできます。こちらも以下のコードで実行してみます。
;;; test_window.scm (include "grBMP.scm") (include "window.scm") (gr_window -2 -2 2 2 #t) (gr_wline -1 -1 1 1 WHITE) (gr_BMP "test_samescale.bmp")
実行後に生成されるtest_samescale.bmpを確認してみましょう。
ちゃんと45度になってますね。同じスケールにしたので右端の空間はあまっている状態です。
今日はこの辺で終わります。