忍者ブログ

ぼんぷろぐ

InDesignとかイラレとかのスクリプトよもやま話

新しいブログに引っ越しました。

こちらのブログはもう更新しませんが、コメント欄は生きてますので疑問、ご指摘などありましたらどうぞ。

[イラレ]
イラレスクリプトで特定の座標を中心にした回転

イラレスクリプトの座標系は、右が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

コメント

お名前
タイトル
文字色
メールアドレス
URL
コメント
パスワード Vodafone絵文字 i-mode絵文字 Ezweb絵文字

プロフィール

kawamoto_α
(あるふぁ(仮))


InDesignで新聞組版のようなことをしています。

ツイッタ

※ブラウザによっては当ブログからDLしたzipファイルが拡張子なしになることがあるようですが、.zipを補って開いてください。



イラレ用トーンカーブスクリプト(¥1500)



クロソイド式角丸長方形スクリプト(¥500)
Illustrator用
InDesign用



イラレスクリプトをキーボードショートカットで実行するやつ(Win用)