和田研フォントキットの肉付け処理を解き明かす (3)
Kazuki Ohta, 2005/05/15
和田研フォントキットの肉付け処理を解き明かす (2)を踏まえて。 さて本日は"cross"を解き明かす事にする。"cross"とは四点の集まりを現しており、"kazari"を定義する際に必要となるモノ。まずは肉づけ処理を行うskeleton2list関数内でcross2point関数がどのように呼ばれるかを確認してみる。
; 1本の線しか通らない場合
((and (eq 2 (length link))(<= 0 (cadadr link) 1))
(setq part1 (cadr link))
(setq type1 (cadr part1))
(setq cross (cross2point part1 (nth (caar ll) points)))
--------- part1 -----------
(MIGI 1
(LINES
(((ANGLE 219.82303 172.279) (BEZIER 244.4074 259.43265)
(BEZIER 276.72842 319.24637) (ANGLE 343.47696 392.01614))
((ANGLE 241.84372 166.0674) (BEZIER 264.38162 245.96619)
(BEZIER 303.05368 305.12848) (ANGLE 364.8063 372.45166)))))
--------- points -----------
((17.008724 94.82636) (383.90768 94.82636) (201.42883 93.091 (LINK-OK T))
(201.42883 15.0) (135.34949 172.92671) (98.54841 289.2855) (15.000006 385.0)
(230.83337 169.1732) (263.65594 285.53195) (353.17212 383.1232))
--------- (nth (caar ll) points) -----------
(353.17212 383.1232)
;
; partからpointへの垂線とその他の2点
;
(defun cross2point (part1 point)
(let ((ret (make-array 4))
(line0 (caadr (assq 'lines (cddr part1))))
(line1 (cadadr (assq 'lines (cddr part1)))))
(case (cadr part1)
(0
(setq line0 (list (car line0)(cadr line0)))
(setq line1 (list (car line1)(cadr line1))))
(1
(setq line0 (reverse line0) line1 (reverse line1))
(setq line0 (list (car line0)(cadr line0)))
(setq line1 (list (car line1)(cadr line1)))))
さて、次々行こう。
(let* ((p0 (nearest line0 point))
(p1 (nearest line1 point))
(l00 (list (float (cadar line0))(float (caddar line0))))
(l01 (list (float (cadadr line0))(float (cadr (cdadr line0)))))
(l10 (list (float (cadar line1))(float (caddar line1))))
(l11 (list (float (cadadr line1))(float (cadr (cdadr line1))))))
l00, l01, l10, l11はそれぞれline0. line1から数字の値だけを取り出したものである。点番号9の場合、l00 == (219.82303 172.279), l01 == (244.4074 259.43265), l10 == (241.84372 166.0674), l11 == (264.38162 245.96619)となる。
とりあえず、現在の関係を図に現してみよう。図は点番号3、つまり漢字"六"の一画目の始点の場合である。コードと見比べてみると良く分かると思う。この場合はたまたまp0とl00, p1とl10が一致している。
さて、ここまで来れば後は簡単だ。
(cond
((or (null p0)(null p1))
(setq p0 (list (float (car point))(float (cadr point))))
(vset ret 0 p0)
(vset ret 1 p0)
(vset ret 2 p0)
(vset ret 3 p0))
(t
(vset ret 0 p0)
(vset ret 1 p1)
(vset ret 2
(plus2
p0
(normlen2 (metric2 p0 p1)
(diff2 l01 l00))))
(vset ret 3
(plus2
p1
(normlen2 (metric2 p0 p1)
(diff2 l11 l10))))))
ret)))
(続く)
[ return ]