イラレスクリプトの座標系は、右がx軸の+方向、上がy軸の+方向で、原点はアートボードを特に動かしてなければ1つ目のアートボード左上になります。単位はpt。
なので座標 (100,100) はこのあたり。
で、今回はこの (100,100) を中心に選択アイテムを30°回転するというスクリプトを書いてみようという話です。
ページアイテムを回転するメソッドといえば rotate ですが、これは6番目の引数で回転の中心を指定できます。選べるのは以下の10個。
Transformation.DOCUMENTORIGIN
Transformation.TOPLEFT
Transformation.LEFT
Transformation.BOTTOMLEFT
Transformation.TOP
Transformation.CENTER
Transformation.BOTTOM
Transformation.TOPRIGHT
Transformation.RIGHT
Transformation.BOTTOMRIGHT
残念ながら中心の座標を数値で指定する選択肢はありません。
しかしDOCUMENTORIGIN、つまり座標でいえば (0,0) なら選ぶことができます。
そこでこう考えます。
(-100,-100) ほど移動
↓
(0,0) を中心に30°回転
↓
(+100,+100) ほど移動
をすれば、点 (100,100) を中心に30°回転したのと同じじゃん!と。
移動のメソッドtranslateと回転のメソッドrotateを使えば次のように書くことができます。
var sel=app.activeDocument.selection;
for(var i=0;i<sel.length;i++){
sel[i].translate(-100,-100);
sel[i].rotate(30,true,true,true,true,Transformation.DOCUMENTORIGIN);
sel[i].translate(100,100);
}
これでできあがり、でもいいんですが、
なんかアイテム1つにつき移動→回転→移動と3つもメソッド使ってると、大量のアイテムを処理するとき重くなるかもしれないし、なんかもうちょっと良い書き方はないかしら、と考えてみます。
イラレのPageItemには transform というメソッドがあります。
これはTransformationMatrix(変形行列、2次元アフィン行列)という、次式のような6つの変数を持つ行列を使って変形を行うものです。
ここでいう変形とは、回転、移動、拡大縮小(縦横比を保持しないものも含む)、シアー、およびそれらの組み合わせです。
たとえば「原点を中心にθ回転」の変形行列は
となります。
ある点(x,y)を「原点を中心にθ回転」した点(x',y')は、行列とベクトルの掛け算を使って、
で求めることができます。
しかし、こんな式は覚えなくても大丈夫です。
Illustratorスクリプトには便利な組み込み関数があって、
getRotationMatrix で回転の変形行列
getTranslationMatrix で移動の変形行列
を得ることができます。getRotationMatrixの引数は普通の角度でOKです。ラジアンを使う必要もありません。
これらを使って上記スクリプトを書き換えると…
var matA = getTranslationMatrix(-100, -100);
var matB = getRotationMatrix(30);
var matC = getTranslationMatrix(100, 100);
var sel = app.activeDocument.selection;
for (var i = 0; i & lt; sel.length; i++) {
sel[i].transform(matA, true, true, true, true, 100, Transformation.DOCUMENTORIGIN);
sel[i].transform(matB, true, true, true, true, 100, Transformation.DOCUMENTORIGIN);
sel[i].transform(matC, true, true, true, true, 100, Transformation.DOCUMENTORIGIN);
}
うーん、これでは何も改善してませんね。
点(x,y)を表すベクトルをrとして、
(-100,-100)移動の変形行列をA、原点を中心に30°回転の変形行列をB、(+100,+100)移動の変形行列をCとしたとき、
rを(-100,-100)移動した点は
Ar
rを(-100,-100)移動して、原点を中心に30°回転した点は
B(Ar)
rを(-100,-100)移動して、原点を中心に30°回転して、さらに(+100,+100)移動した点は
C(B(Ar))
で表せます。
そして、行列の掛け算はなんと、
結合則が使えるのです!
すなわち、
C(B(Ar)) = (CBA)r
これは事前にCとBとAを掛け算した変形行列を求めておけば、変形1回で「(-100,-100)移動して、原点を中心に30°回転して、さらに(+100,+100)移動」したのと同じ状態にできる、ということです。
んで、イラレはその変形行列の掛け算にも関数を用意してくれています。concatenateMatrixというやつです。
var matA = getTranslationMatrix(-100, -100);
var matB = getRotationMatrix(30);
var matC = getTranslationMatrix(100, 100);
var matABC = concatenateMatrix(concatenateMatrix(matA, matB), matC);
var sel = app.activeDocument.selection;
for (var i = 0; i < sel.length; i++) {
sel[i].transform(matABC, true, true, true, true, 100, Transformation.DOCUMENTORIGIN);
}
なんか上はごちゃごちゃしましたけど、forループがシンプルになったので今度こそできあがりでーす。
ちなみにconcatenateTranslationMatrixとかconcatenateRotationMatrixとか使うともう少し短く書くこともできます。詳しくはOMビューワとか
こことか見てください。
おしモアイ
PR