角のある形 — SAT
円は中心と半径だけだから、重なりの判定は中心の距離一本で済む。凸多角形どうしでは、距離一つでは内と外が決まらない。代わりに射影を使う。
分離軸定理(SAT, Separating Axis Theorem)。二つの凸形が重なっていないなら、その間に一本の直線(分離軸)が必ず引ける。どちらかのエッジに垂直な向きへ両者を射影して、できた区間が重ならない向きが一つでもあれば離れている。全エッジの法線を試して、どれでも区間が重なるなら衝突。重なり量が最小の向きが、最短で押し出せる方向(MTV, Minimum Translation Vector)になる。凸形にしか使えず、凹んだ形は凸に分割してから当てる。
ある向きの軸へ、多角形の全頂点を射影する。頂点の座標と軸の単位ベクトルの内積が、その軸の上での位置になる。最小と最大を取れば、多角形がその軸に落とす影が一区間に縮む。二つの多角形の影が重なるか離れるかで、その軸が分離軸かどうかが決まる。下は一本のエッジの法線を軸にして、二つの多角形を軸の上へ射影した影を引いている。
二本の影が離れている瞬間は、この軸が分離軸になっていて、二つの多角形のあいだに一本の隙間の線が引ける。左の多角形が寄って影が重なり始めると、隙間の線が消える。影の重なり overlap が正なら、この軸では分離できていない。一本の軸で離れていれば衝突ではないが、重なっていてもまだ衝突とは言えず、他の軸では離れているかもしれない。
衝突を確かめるには、両者の全エッジの法線を軸にして射影を繰り返す。どの軸でも影が重なるなら衝突で、そのとき重なり量が最小だった軸が、最短で押し出せる向きになる。その向きへ重なり量の半分ずつ、二つの多角形を引き離す。下は多角形を箱の中で漂わせて、ぶつかったペアを塗りつぶし、最小重なり軸に沿って離している。
ぶつかったペアが塗りつぶされて、最小重なり軸の向きに離れていく。判定の中身は射影の繰り返しで、エッジが多いほど試す軸が増える。円が中心の距離一本だったのに対し、多角形は全エッジの向きを試すので、判定のコストが形の複雑さに乗る。minOverlap / 2 を片方だけに寄せれば質量の偏った押し戻しになり、+ 0.1 を抜くと接したまま再びめり込んで震えやすくなる。