仮想計算機構

IT業界と無縁な派遣社員のブログ

【奥村本】座標の取り方を変えて線を描画する

奥村さんのアルゴリズム本をSchemeでやるシリーズが滞っていたので進めます。
ちなみにこういう取り組みって権利的にどうなのか微妙だなーと思っていたところ以下のサイトで権利問題がクリアにしてあったのでとりあえず安心しています。
GitHub - okumuralab/algo-c

今回の取り組み

今までは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が生成されました。
f:id:riverta1992:20200524171913j:plain
本来であれば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を確認してみましょう。
f:id:riverta1992:20200524172249j:plain
ちゃんと45度になってますね。同じスケールにしたので右端の空間はあまっている状態です。

今日はこの辺で終わります。

参考文献