今回は、交差の判定にベクトルを使います。
図1
上の図では、2ベクトルが独立な為、変数s,tを用いて ここまではいいですか?
で、Pが図における斜線部にある時に、2つの線分が交差することになるのが分かると思います。
条件にはsとtが関わってくるので、この2つをどうにか数式で表しましょう。
ここまで来ればだいたい想像は出来てくるのではないかと思います。
というわけで、(式9)と(式10)をチェックすればいいわけです。が、
(図2)
そこで、点Oから見たときのベクトルの内積を使います。
この判定は∠AOBだけでなく、∠APBと∠OAP(もしくは∠OBP)に対してもやらなければなりません。
さぁやってまいりました、いよいよソースです。 // 線分の当たり判定 (x1,y1)-(x2,y2) × (x3,y3)-(x4,y4) int CheckLineCrossing(int x1,int y1,int x2,int y2,int x3,int y3,int x4,int y4){ int S,T,D; // 一時変数を宣言 // 分母を先に計算。計算量を減らすため、分子は後で行う。 D = (x3-x1) * (y4-y1) - (y3-y1) * (x4-x1); // D の符号に応じて分岐 if(D < 0){ S = (y4-y1)*(x2-x1) - (x4-x1)*(y2-y1) T = (x3-x1)*(y2-y1) - (y3-y1)*(x2-x1) return S <= 0 && T <= 0 && (S+T)/D >= 1 ; } else if(D > 0){ S = (y4-y1)*(x2-x1) - (x4-x1)*(y2-y1) T = (x3-x1)*(y2-y1) - (y3-y1)*(x2-x1) return S >= 0 && T >= 0 && (S+T)/D >= 1 ; } // D = 0 の時には、点が線分の上かどうかを判定する。 return (x3-x1)*(x4-x1)+(y3-y1)*(y4-y1) <= 0 || (x3-x2)*(x4-x2)+(y3-y2)*(y4-y2) <= 0 || (x1-x3)*(x2-x3)+(y1-y3)*(y2-y3) <= 0; }こんな感じで。読みにくかったらごめん。 色々なところに"-x1"や"-y1"があるのは、さっきまでの話をずっと (x1,y1)との相対座標でやっていたからですね。 まだまだ最適化が出来そうですが、その辺は使う人にお任せしましょう。 | |
余談1 |
余談2 |