■default ---■fontsize --70% --80% --100% --120% --140% --- --■scroll_switch

illustrator javascript で射影変換

射影変換(perspective transform)
illustrator javascript

イラレのスクリプトで例えば四角のパスアイテムを1000個一度に大きさを半分にするのは簡単です。
var v = 0.5;
var ar= [].slice.call(activeDocument.activeLayer.pageItems);
var hw = ["height","width"];
for(var i in ar ){for(var j in hw ){ar[i][hw[j]] *= v;}}

動かしてないけど、こんな感じでいけると思います。
resize()使ってもいいし。
角度を変えるのも簡単。rotate()というのが有ります。
移動も簡単です。
---------------------------
illustratorでオブジェクトを選択するとバウンディングボックスというのが出ます。
出ない場合はeを押すとでます。objectの外形を取った長方形です。
角を選択してドラッグすると「自由変形」ができます。
拡大縮小や、回転。
もう少し深い操作があります。
コントロールボタンを押しながら、ドラッグすると歪ませた形にできます。
「シアー」とか言うらしいですが、とにかく歪んだ感じになります。
で、これをscriptで行いたいのですが。

----------------------------
まず、目に付くのが
transform()というメソッド。
transformationMatrix というマトリックスオブジェクトに6つくらい数字を入れてやれ、みたいなのがあります。
ところが、詳しく調べてみるとこれはひし形しか作れません。
なんつうか、正方形から台形を作りたいのです。
ついでに、その中にあるオブジェクトも一緒に動くみたいな。

それで調べた結果
ひし形にする変換をアフェイン変換
台形みたいにもっと自由な形にするのを射影変換(perspective transform)
というらしいです。
で、この射影変換はillustratorのオブジェクトではsupportしていません。

で、射影変換するには
長方形を任意の四角形に変換する行列
+=http://ynomura.dip.jp/archives/2014/01/post_48.html
のような計算をしないといけません。
小卒程度の知能の私には何を言ってるのかさっぱり分かりません。
なので、ジャバスクリプトの変換ソースも作れません。
OpenCVにもgetPerspectiveTransform()とPerspectiveTransform()という関数があるので、それを見て
c++からじゃばすくりぷとに書き直せばよさそうですが、勘弁してほしいです。
------------------------------
で、解決編ですが。
プログラムソースを載せたいのですが、汚いのと、長いので、肝の部分だけ記録しておきます。
・web用に作られたperspective-transform.jsというのがどこかの天才外人が作ってましたのでそれをダウンロード。
+=http://uncorkedstudios.com/blog/perspective-transforms-in-javascript
ホームページとかで画像をCSSで歪ませるのに使うみたいです。
で、これがそのまま使えます。

var ar = [一個目の四角の4点のXY、2個目の四角の4点のXY];
//例えばvar ar = [ [[0,0],[0,100],[100,0],[100,100]] ,[[1,0],[0,100],[100,0],[100,100]] ] ;
//イラレなので、四角書いてそのポイントを入れるみたいなことになると思います。for(var j = 0 ; j < 4 ; j++){ ar[0][j] = ov.pathPoints[j].anchor;}
var srcCorners = [ar[0][0][0] , ar[0][0][1], ar[0][1][0] , ar[0][1][1],ar[0][2][0] , ar[0][2][1],ar[0][3][0] , ar[0][3][1] ];
var dstCorners = [ar[1][0][0] , ar[1][0][1], ar[1][1][0] , ar[1][1][1],ar[1][2][0] , ar[1][2][1],ar[1][3][0] , ar[1][3][1] ];
var perspT = new PerspT(srcCorners, dstCorners);

これで、なんか行列ができるので
xy2 = perspT.transform(x,y);てのをやってやると xy2に変換した座標がきます。
これを 動かしたいオブジェクトのパスポイント全部で繰り返せばOK。
///////////////////////////
ov = 動かしたいパスオブジェクト;
var p_ar = [].slice.call(ov.collections[i].pathPoints);
for(var i in p_ar){perspective_transform_one(p_ar[i],perspT);}
function perspective_transform_one(tg,perspT){
var ar =["anchor","leftDirection","rightDirection"];
for(var i in ar ){tg[ar[i]] = perspT.transform(tg[ar[i]][0], tg[ar[i]][1]);}
}
///////////////////////////
こんな感じでしょうか。ハンドルも一緒に動かさないと、面白い形になってしまいます。
これを応用すればパースペクティブを適用したり、キャリブレーションかけたりできます。



スポンサーサイト
ブログ内検索ワード
マジック / フラリッシュ / デザイン / ~のコツ / プログラム関連 /