N点のXY座標を順に繋いだ折れ線が、自己交差してるかどうかを調べたい。
要は「多角形の自己交差判定」の「始点と終点を結ぶ線が無いバージョン」なので、参考になるかと思い多角形の自己交差で調べてみたが、「辺を全て別々の線分と見なした上で、全線分対の交差判定」というものしか見つからなかった。(探し方が下手なだけ)
それでもいいんだけど、やっぱり全ての線分は2つずつ繋がっているということを利用すれば、計算量減らせるんじゃ無いかという思いもある。
全線分対の交差判定は、Bentley-Ottmannのアルゴリズムがある。
前提を回避する方法はあるが、端点を微少にずらすとか泥臭い実装が必要になる。ただし、「全ての交点を発見する」でなく、「交点の存在有無を発見し、最初に見つかった1点を返す」だけなら、交点と端点、交点同士が同一x座標にあってはいけないという問題は無視できる。
これの応用でできそう?
節点や始終点が他の線分上にあった場合にも正しく動作するよう気をつけるべきことはまだ整理できていない。
全ての交点を見つけるBentley–Ottmannアルゴリズムでは、交点というイベントを追加するため、Qは優先付きキューである必要があるが、1点見つかったら終了する今回のアルゴリズムではイベントは追加しないため、初期化時に1回ソートすればよく、リストでよい
二分探索木は、線分を「掃引線Lと各線分の交点のy座標」順に管理する。
今回の処理では、交点が見つかったらbreakする、つまり全ての線分はその時点までは交わっていない。線分の上下の順序は交差したときのみ入れ替わるため、あるx座標における線分の”順序”は、xを動かしても保たれているといえる。
しかし、“値”(y座標)はx座標毎に当然、変化する。挿入したり、ある点の直上直下の線分を探索する場合は、「現在のx座標でのy座標」を基準に参照しなければならない。
また、折れ線なので「同一端点から始まる2本の線分」が存在する。もしこの2本が同時にTに存在するとき(“<“のような形)、上になる方と下になる方の位置関係が正しく挿入されなければならない。それには端点のy座標だけを基準にしては不足で、y座標が同じ場合は傾きの大きさも比較対象にする必要がある。
二分探索時の比較ごとにx座標を与えて演算する必要があるため、固定値で比較する単純な二分探索木と比べて、若干コストが重くなる。
この辺上手くする方法はないかな。