javascriptでベジエ曲線をコントロールする

最終更新日

Comments: 0

暑い日々が続いていますが、皆様はいかがお過ごしでしょうか。こう暑いと水辺が恋しくなります。次のお休みは海でも行ってみようかなと思いつつ仕事をこなしていますが、ここ数年泳いだ事が無いので少々怖かったりもします。
さて、本題。illustratorはベジエ曲線を利用した描画システムが特徴的なのは皆様ご存知の通りなのですが、このベジエ曲線ってスクリプトから正確にコントロールするには、それなりの知識が不可欠な訳です。
理論上ではバーンスタイン基底関数なんかが出て来て非常に難解で複雑なものなのだけど、実はこのベジエ曲線、実装はとても容易でわかり易かったりするんだ。

まずは、下図の2つのアンカーポイントの間にある曲線の中点にアンカーポイントを追加する場合を考えて見よう。

この場合、コントロールポイントは双方のanchorと開始点のleftDirection、終点のrightDirectionの4点。

この4点を順番に結び、出来た3本の線分の中点をA、B、Cと定義し、順番に結び線分AB、BCを得る。

ここで、点Aは新しい開始点のleftDirection、点Cは終点のrightDirectionとなる。
次に線分ABの中点Dと線分BCの中点Eを定義する。

この二点は新規に得られるアンカーポイントのleftDirectionとrightDirectionとなる。最後に点Dと点Eを結ぶ線分の中点が新規に追加されるアンカーのanchorとなる。
わりと、単純な反復で処理できるんです。
この例では中点を追加する場合でしたが、全線分の分割比率を変える事によって任意の位置にアンカーポイントを増設できます。

上記の手順をJavascriptで書くと

var pt = new Array();
var ratio = 0.5;
var slct = app.activeDocument.selection[0];

pt[0] = slct.pathPoints[0].anchor;
pt[1] = slct.pathPoints[0].rightDirection;
pt[2] = slct.pathPoints[1].leftDirection;
pt[3] = slct.pathPoints[1].anchor;

pt[4] = splitPath (pt[0], pt[1], ratio);
pt[5] = splitPath (pt[1], pt[2], ratio);
pt[6] = splitPath (pt[2], pt[3], ratio);

pt[7] = splitPath (pt[4], pt[5], ratio);
pt[8] = splitPath (pt[5], pt[6], ratio)

pt[9] = splitPath (pt[7], pt[8], ratio);

var ln = app.activeDocument.pathItems.add();
ln.stroke = true;
//start point
nwPt = ln.pathPoints.add();
nwPt.rightDirection = pt[4];
nwPt.anchor = slct.pathPoints[0].anchor;
nwPt.leftDirection = slct.pathPoints[0].anchor;

//add point
nwPt = ln.pathPoints.add();
nwPt.leftDirection = pt[7];
nwPt.anchor = pt[9];
nwPt.rightDirection = pt[8];

//end point
nwPt = ln.pathPoints.add();
nwPt.leftDirection = pt[6];
nwPt.anchor = slct.pathPoints[1].anchor;
nwPt.rightDirection = slct.pathPoints[1].anchor;

function splitPath (pt1,pt2,ratio){
var result = new Array();
 
result[0] = pt1[0]-(pt1[0]-pt2[0])*ratio;
 
result[1] = pt1[1]-(pt1[1]-pt2[1])*ratio;
 
return result;
 
}

単純なコードなので解説も必要ないぐらいだと思うけど、一応要点だけ。パスポイントが2点のパス以外ではエラーになるので注意。
選択したパスのアンカー情報を取得して、パスの分割比率(ratio)に応じた部分にアンカーポイントを追加した状態のパスを生成するんだ。
splitPathファンクションは2点間の直線上のratioに応じた比率の座標を取得するための関数。

ESTK3.5は相変わらず使えないやつですが、データブラウザはとっても重宝します。最近は大まかな編集をCotEditを使っています。

ten_a

Graphic Designer, Scripter and Coder. Adobe Community Professional.

シェアする

コメントを残す