■ 四捨五入して並べればいいんだって…やっと気づきました(^_^;)
スクリーンショット 2018-09-01 10.19.24

 おつかれさまです。@gorolibです。

 Illustratorのスクリプトを組む際に、選択オブジェクトを座標順に並べてから処理させることがよくあります。

 これは、選択オブジェクトの配列が、座標順ではなく「重なり順」となっているためであり、そのまま処理するといちばん手前(最前面)のオブジェクトが先頭になってしまうんですね。これは処理としては不都合なケースが多いんです。

 そこで、sort関数を使って、座標順に並べるのですが、今度は0コンマいくつ違う(イラレあるあるです)だけで、並びが逆転してしまうことがある。ある時、ふと気付きました。

 四捨五入してから並び替えればいいんじゃね?

 実は、単位変換の問題が気になっていたのですが、何のことはない、ポイント(以下pt)単位で四捨五入すればよかったのです。


■ 1pt(約0.353ミリ)の半分の値を人為的に使うか?

 実は、スクリプト内部で扱う座標や大きさなどの数値は、すべてpt単位になっています。これは環境設定の単位設定にはよりません。つまり、内部数値を四捨五入するということは、ptを小数点第1位で四捨五入するということになります。

 これは、1pt(約0.353ミリ)の半分(約0.177ミリ)未満の値を丸めるということです。もちろん実際の座標を移動するわけではなく、あくまでスクリプト内部で並び順の基準として使うだけです。

 このとき、約0.177ミリ未満の値を人為的に(デザインとして)ずらす、ということはあまり考えられません。もちろん、線幅としては、0.1ミリ、0.15ミリという表現はありえますが、高さを揃える際に、0.15ミリだけ「わざとずらす」事は考えづらいのです。

 そこで、並び替え関数を以下のようにして、最近使い始めました。配列(例えば、app.activeDocument.selection)を渡すと、オブジェクトの左上の座標を基準に並び替えて、戻してくれます。

 私は、できるだけプログラムを短くして、すべてグローバル変数でまかない、elseがキライ、ピリオドも打たないという変態なので(笑)、適宜追記して使ってくださいませ…
─────
function SORTfn(f0){
f1 = []
for(f=0; f<f0.length; f++) f1.push(f0[f])
f1.sort(
function(a,b){
a0 = Math.round(a.position[0])
a1 = Math.round(a.position[1])
b0 = Math.round(b.position[0])
b1 = Math.round(b.position[1])

if(a1 > b1) return -1
if(a1 < b1) return 1
if(a1 == b1){
if(a0 < b0) return -1
if(a0 > b0) return 1
if(a0== b0) return 0
}
}
)
return f1
}
─────

お役に立てれば幸いです!ではでは出羽の海。