円と線分の当たり判定

アバター
ナムアニクラウド
記事: 16
登録日時: 15年前
住所: 茨城県

円と線分の当たり判定

投稿記事 by ナムアニクラウド » 13年前

 いつの間にか(ではないが)一ヶ月経っていたorz
不定期にも程がありますが続きます ^q^
今回は「円と線分の当たり判定」です。

 ここでは、ベクトルを太字で表すことにします。

円と線分が当たっているとき
c-l1.png
c-l1.png (9.6 KiB) 閲覧数: 243 回
 まず図のように、線分ABと円Oがあります。
円に関する当たり判定なので、円の中心からの距離を考えてみましょう。

 いま、点OからABへ垂線を下ろし、垂線の足をHとします。
すると、線分ABと点Oの距離はまさにOHの長さとなります。

 いま、図より「(1):点Hが円Oと当たっている ⇒ 円Oが線分ABと当たっている」となることが分かります。
もし「点Hが円Oと当たっている ⇔ 円Oが線分ABと当たっている」となれば、HとOの当たり判定で考えることができます。
そうなれば、あとは円と点の当たり判定を考えるだけなので簡単ですね。
 そこで、(1)の逆について考えてみましょう。
「(2):HがOと当たっている ⇐ OがABと当たっている」の対偶は「(3):HがOと当たっていない ⇒ OがABと当たっていない」です。
線分AB上で一番点Oに近い点はHなので、点Hと円Oが当たっていないならば、線分上に円Oとの共有点はありません。よって、(3)は真となり、対偶である(2)も真です。
つまり、「点Hが円Oと当たっている ⇔ 円Oが線分ABと当たっている」が成り立ちます。

点と直線の距離
 点Hが円Oと当たっているための条件は、OHが円の半径より小さいことです。Oの半径をrとしましょう。
直線と点の距離を調べるには、ベクトルの「外積」を用いることができると以前に説明しました。さすがに忘れてますよね(^^;)→ベクトルの外積と当たり判定
この方法を使って、OHの長さを求めましょう。
求めるといっても公式に代入するだけです。線分ABと点Oとの距離OHは
  OH = |ABAO|/|AB|
となります。
そして、当たり判定の条件は単純に OH 0(鋭角)、BOAB > 0(鋭角)、APAB > 0(鋭角)、BPAB < 0(鈍角) となります。
点Pは端点Bの方へはみ出したので、点Pから線分ABまでの最短距離はPBとなります。

結論
 以上のことから、次のように当たり判定をします。
半径rの円Oと、線分ABがあるとき、円と線分の間の最短距離をdとすると、
 (i) AOAB < 0 のとき d = AO
 (ii) BOAB < 0 のとき d = BO
 (iii) それ以外のとき d = |ABAO|/|AB|
であり、d < r ならば、OとABは当たっている。
添付ファイル
c-l2.png
c-l2.png (10.05 KiB) 閲覧数: 249 回

アバター
GRAM
記事: 164
登録日時: 15年前

RE: 円と線分の当たり判定

投稿記事 by GRAM » 13年前

毎度横槍をすみませんw

基本的な考え方はその通りなのですが、実際にはもっと最適化できます。

具体的には次のようなベクトルa,bで
c = t a (0≦t≦1)をあらわすことです。
無題.png
無題.png (5.38 KiB) 閲覧数: 140 回
( ta - b )・a = 0より t = a・b/a^2 で簡単に求まります。

後は、t > 1なら t = 1へ t< 0なら t = 0へクランプしてやれば、円の中心の位置ベクトルbから方向線分aへの最短距離の方向を示すベクトル

c-bが一瞬で得られます。

ふっふっふっ

アバター
ナムアニクラウド
記事: 16
登録日時: 15年前
住所: 茨城県

Re: 円と線分の当たり判定

投稿記事 by ナムアニクラウド » 13年前

>GRAMさん
 横槍ありがとうございます\(^o^)/
こうやって、より優れた答えが投稿されるとなんだか複雑な気持ちですが、とても勉強になって面白いです。
当たり判定は奥が深いですが、その割にパブリックな資料は少ないような気がしています。
そこでこのように投稿をして、コメントを頂くことでいろいろな人の考え方を吸収していきたいと思っています。
そういうわけで、これからもどんどんコメントお願いします!ばっちこい!