曲線同士が接しているということは、その凸包も接していることになる。 凸包の共有部分を調べ、絞り込むことで交点を得ることが出来るだろう。 (凸包が全く同じ形状の場合、絞り込めないので、半分に切るなどの 対処が必要。)
なんとなく思いついた流れ
交点を求める( 曲線A, 曲線B){
if( 2つの凸包が接していない ) return null;
do{
clipA[] = 曲線A が、曲線Bの凸包内部である部分
clipB[] = 曲線B が、曲線Aの凸包内部である部分
}while( ClipA.length == 1 && ClipB.length == 1 && 収束していない );
if( ClipA.length == 0 || ClipB.length == 0 ) return null;
if( ClipA.length == 1 && ClipB.length == 1 && 収束した ) return 座標;
result[] = {};
for( ClipA.length 回 ){
for( ClipB.length 回 ){
result += 交点を求める( ClipA[cnt1], ClipB[cnt2] );
} }
return result;
}
動作例
最近作ったデモの画面
試行錯誤して気づいたこと
- 実数判定のため、虚数部の0チェックを厳しくしすぎるとうまくいかないことがあった。
- 収束判定がきつすぎて、凸包が細かくなりすぎて解を取りこぼした。
- 曲線が凸包内である区間を調べるときは、いったん t < 0, 1 < t の領域も含めた解をを得てから、マイナスだけの区間と1より大きい領域だけにある区間を省く。残った凸包内である区間の先頭がマイナスだったり、区間の終端が1より大きかった場合、それぞれ始点を0, 終点を1 とする。
- 同じ交点に収束する曲線同士だけを比較し、関係ない曲線から切り出されたものとは比較しない。

元の状態
