Tclでベジェ曲線!
tclでもベジェを操作して自由曲面を扱えるようなサンプルを作ってみました。
元のファイルは、Shadeのサンプルtclです。
1.ベジェの基礎
ベジェ曲線の定義は
P(t) = (1-t)^3*P0 + 3*t*(1-t)^2*P1 + 3*t^2*(1-t)*P2 + t^3*P3
で表せます。幾何学的に表すともっとわかりやすいのですが、
ここでは
P0:最初のアンカーポイント
P1:最初のアンカーポイントのoutハンドル
P2:次のアンカーポイントのinハンドル
P3:次のアンカーポイント
で、P(t)はこの曲線状の座標を表します。各P0〜P3,P(t)はx,y,zの座標を持つベクトルです。
まず4つのコントロールポイントを結ぶ3本の直線を各々tと1-tで分割します。
分割した点を結んだ直線2本をさらにtで分割します。
最後の直線もtで分割したポイントが助変数tの位置です。
詳しくは参考文献をどうぞ。
C++では、Shadeで提供されているvec3というクラスを使って
vec3 bezier = b[0] * s3 + b[1] * ( 3 * s2 * t ) + b[2] * ( 3 * s * t2 ) + b[3] * t3;
と簡単にかけます。tclではx,y,z別々に計算したほうがいいかもしれません。
Shadeにあるtclのサンプルから、ベクトルの加減算とスカラー値をかけるprocを作成して
set v3NewPoint [ plus_vec [ plus_vec \
[ \
plus_vec [mul_vec_scal $v3Anchor2 $s3 ] \
[mul_vec_scal $v3Out_hdl2 [ expr $s2 * $t1 * 3 ] ] \
] \
[ mul_vec_scal $v3In_hdl1 [ expr $s1 * $t2 * 3 ] ]\
] \
[ mul_vec_scal $v3Anchor1 $t3 ] ]
と書いてみました。
2.ベジェを助変数 t で分割
3.ベジェを距離で分割
どうやらベジェの t は同じ長さにベジェを切り分けてくれないことにお気づきと思います。
元の式が3次元なのでどうしてもそうなります。ここでは簡単に等距離に分割してみました。
最初に大雑把に長さを求めnで割ります。そこそこ細かくtを分割して、距離を求めながらn等分しています。
距離の求め方は、ベジェの2点を二乗して足して平方根を取っているだけです。
2.との違いがわかるでしょうか?
サンプルコード:DivideBezier_l.zip
4.参考文献
「私家版 BEZIER 講座」 著作 加藤俊明 http://www.bekkoame.ne.jp/~t.katoh/
(ベジェのお師匠様です。)
「On-Line Geometric Modeling Notes」Kenneth I. Joy http://graphics.cs.ucdavis.edu/CAGDNotes/CAGD-Notes.html