テキストフレームの座標を比較して順序をソートするメソッドを仕込んでおいたのに、どうしても順序が正しく並び替えられない…という事態に遭遇して解決したのでメモ。
改めて勉強になりました…。
オチ
UI上、絶対に目視では確認できない微小な誤差(-5.6843418860808e-14
)が発生していた。
どういうことかというと下図のとおり。
e-14
とはなんぞや
指数表記です。
5e-14
は 5 * 10-14 になります。
回避するには
要するに、VS Codeのデバッガー上もそこまで小さな値は端折って表示されていた(当然InDesignのUI上もそんな小さな値まで表示されない)。
Array.sort()
メソッドの中で、取得する値をある程度の概数にするほかないんだけど、方法論としては2つ考えた。
- 値を取得するタイミングで概数にして変数に渡す(その変数の差を取る)
- 値はそのまま取得して差を取得したものを概数にする
JavaScriptの浮動小数点にまつわる問題は計算のタイミングで起きるよな、と思って、前者で対応することにした。具体的には小数点以下3桁が有効になるように四捨五入。
found.sort(function (a, b) { var digits = 3; var roundA = Math.round(a * Math.pow(10, digits)) / Math.pow(10, digits); var roundB = Math.round(b * Math.pow(10, digits)) / Math.pow(10, digits); return roundA - roundB; });
みたいな感じ。
実際にはgeometricBounds
相手だったのでもうちょっと複雑でした。