2線分の交点
線分AB、CDがあったときに、その交点を求めるには?
要素は2次元空間内に存在するものとします。
解説
線分AB上の任意の点Pは、媒介変数 r を用いて、以下のように表現できます。
P = A + r ( B - A ) ( r は[0~1]の値を取る) ・・・式①
同様に、CD上の任意の点Qも、媒介変数 s
を用いて、以下のように表現できます。
Q = C + s ( D - C ) ( s は[0~1]の値を取る) ・・・式②
PとQが同一点になる場合の r と s を求めれば、ABとCDの交点は求まったことになります。
というわけで、P = Q を解きます。
P = Q
⇔ A + r ( B - A ) = C + s ( D - C )
X、Yに関する連立方程式にします。
⇔ Ax + r ( Bx - Ax ) = Cx + s ( Dx - Cx
)
Ay + r ( By - Ay ) = Cy + s ( Dy - Cy
)
これを解きますと、
r = { (Dy - Cy)(Cx - Ax) - (Dx - Cx)(Cy -
Ay) }
/ { (Bx - Ax)(Dy - Cy) - (By - Ay)(Dx -
Cx) } ・・・式③
s = { (By - Ay)(Cx - Ax) - (Bx - Ax)(Cy -
Ay) }
/ { (Bx - Ax)(Dy - Cy) - (By - Ay)(Dx -
Cx) } ・・・式④
演算回数を減らすために、一時変数を用います。
ACx = Cx - Ax
ACy = Cy - Ay
BUNBO = (Bx - Ax)(Dy - Cy) - (By - Ay)(Dx
- Cx )
として、
r = { (Dy - Cy)ACx - (Dx - Cx)ACy } / BUNBO ・・・式⑤
s = { (By - Ay)ACx - (Bx - Ax)ACy } / BUNBO ・・・式⑥
・平行チェック
r、s を求めようとしたときに、r、s が求まらない場合があります。すなわち、BUNBOがゼロの場合です。このとき、2線分は平行であり、交差しません。
・重なりチェック
BUNBOがゼロで、さらに、式⑤、⑥の分子もゼロの場合には、2線分は重なりあっています。
・線分交差チェック
式①、②より、r、s が共に 0~1 の間の値として求まらなければ、2線分は交差していないとなります。
r、s 個別に言うと、
r < 0 :点Pは、点Aより手前
r > 1 :点Pは、点Bより奥
s < 0 :点Qは、点Cより手前
s > 1 :点Qは、点Dより奥
となります。
考察
r、s の数値が0、1に非常に近い数値の場合には、演算誤差によって、
交差していないのに交差していると判定される場合や、
交差しているのに交差していないと判定される場合
がないとは言えません。
このような場合に配慮して、実用においては、交点計算に加えて、
・点と直線の距離計算を用いて、線分の端点がもう一方の線分上にあるかの判定を行う
もしくは、
・点と直線の半空間テストを用いて、線分の2端点がもう一方の線分をまたいでいるかかの判定を行う
必要があります。
ダウンロード
参考
Graphics Gems Ⅲ:Faster Line Segment Intersection