next up previous
Next: 10 xlispstat Up: 9 例題:Xwindow操作機能の追加 Previous: 9.3 マウス操作イベントをとる例

9.4 C 曲線の表示

以上の拡張を行うと以下のリスプ関数を利用できるようになります.
     (GRAPH-INIT)
     (GRAPH-MOVETO x y)
     (GRAPH-LINETO x y)
     (GRAPH-CIRCLE x y radius)
     (GRAPH-CLOSE)
     (GRAPH-CLEAR)
     (GRAPH-GETPIXEL x y)
     (GRAPH-PUTPIXEL x y value)
graph-initにより初期化をし,graph-movetoでペンを移動し,graph-linetoで 線を描くという単純なモデルです.mech環境のxlispにはこのグラフィックス 機能が付加してありますから,Xwindow環境でこれらの関数を使うと図を描く ことが可能です. たとえば,C カーブは以下のような関数で描くことが可能です.
(setq pi/4 (/ 3.1415926 4))
(setq 1/sqrt2 (/ 1.0 (sqrt 2.0)))
(defun float-vector (&rest l) (mapcar #'float l))
(defun point (x y) (float-vector x y))
(defun x (p) (car p))
(defun y (p) (cadr p))
(defun v+ (p1 p0)
  (point (+ (x p1) (x p0)) (+ (y p1) (y p0))))
(defun v- (p1 p0)
  (point (- (x p1) (x p0)) (- (y p1) (y p0))))
(defun scale (s v) (point (* (x v) s) (* (y v) s)))
(defun distance (p0 p1)
  (let* ((dv (v- p1 p0)) (dx (x dv)) (dy (y dv)))
        (sqrt (+ (* dx dx) (* dy dy)))))
(defun rotate (v rad)
  (let ((x (x v)) (y (y v)))
        (point (+ (* (cos rad) x) (* (sin rad) y))
                (- (* (cos rad) y) (* (sin rad) x)))))
;;;
(defun draw-line (p0 p1)
  (graph-moveto (x p0) (y p0))
  (graph-lineto (x p1) (y p1)))
;;;
;;;     C curve
;;;
(defun draw-ccurve (&optional
                    (p0 (point 190 300))
                    (p1 (point 450 300))
                    (min 20))
  (cond
   ((< (distance p0 p1) min) (draw-line p0 p1))
   (t (let ((p2 (v+ p0
                   (scale 1/sqrt2
                          (rotate (v- p1 p0) pi/4)))))
        (draw-ccurve p0 p2 min)
        (draw-ccurve p2 p1 min)))))
> (graph-init)
T
> (draw-ccurve (point 170 300) (point 470 300) 50)
T
> (graph-clear)
T
この例からわかるように,Lispでは,リストを用いて数値計算で用いるベクト ルや行列を表現することも容易です.
図 1: C カーブ
\includegraphics[width=7.0cm]{/home/inaba/eps/lecture/fig/ccurve.eps} \includegraphics[width=6.0cm]{/home/inaba/eps/lecture/fig/ccurvefine.eps}
最小の辺を50ではなく,5にしたものが図の下の方のカーブです.

generated through LaTeX2HTML. M.Inaba 平成18年5月6日