線分と円の重なり判定

アバター
MoNoQLoREATOR
記事: 284
登録日時: 14年前
住所: 東京

線分と円の重なり判定

投稿記事 by MoNoQLoREATOR » 12年前

涼雅さんのこの日記に触発されたので作ってみました。
偶然3ヶ月程前に筋道を立てていたので、あとはこれをプログラムにするだけじゃん楽勝wwwwとか思っていたのですが、線分や法線を司るクラスを作ったのが半年以上前で、仕様がめちゃくちゃだったのでそこから作り直しましたw
とりあえず、筋道はこうです…と説明に入る前に、定義を確認しておきます。
涼雅さんは”接触”判定について記事を書いておられますが、私は今回”重なり”判定について記事を書きます。
私は”接触”,”重なり”の定義は次の画像が示す通りだと考えています。
画像
それでは、筋道を説明いたしましょう。
(ⅰ)線分の始点または終点が円の範囲内であればその時点で return true
(ⅱ)線分の法線の中で、円の中心を通るものがなければその時点で return false
(ⅲ)「線分と、円の中心を通る法線の交点」が円の範囲内であれば return true
(ⅳ)return false
ある一箇所を調べてその時点で重なっているかどうか判断できれば即座に関数を脱出して結果を返す。
こうすることで、運がよければ非常に短い時間で判定することができます。
(ⅱ)について解説します。(ⅰ)を素通りしているということは以下のいずれかの状態であるということがわかります。
画像
ここでは図の③の状態だとわかった場合に「重なっていない」と判定して脱出しているわけです。
あとは図の②か③のどちらかということになるので、これは交点と円との距離を調べればわかりますね。
というわけで、以下ソースコードです。
► スポイラーを表示
ソースコードの量は多いですが、実際の処理はそんなに多くないです。
おそらくline.hの中身が意味不明だと思いますが、
「座標x,yを保持し、それを基準とした相対的情報(傾き、切片、始点、終点)を記録する」
というコンセプトで作ったのですと言えば理解できる…かな…?

まあそんなわけで、これが私の回答です。
最近は専らActionScriptばかり書いていて、凄まじく久しぶりのC++だったのでなんだか初心に戻ったみたいで楽しかったです。
クラス定義の最後に;をつけ忘れてエラーが大量に出たときは懐かしくて噴き出したなんてことは決してありませんでしたからねw?

それでは、良いプログラミングライフを!
最後に編集したユーザー MoNoQLoREATOR on 2012年11月24日(土) 02:39 [ 編集 1 回目 ]

アバター
みけCAT
記事: 6734
登録日時: 14年前

Re: 線分と円の重なり判定

投稿記事 by みけCAT » 12年前

前の日記にも書いてないのに、なんでいきなり3次元が出てくるのでしょうか?
なぜ3次元なのに画像は平面的に書いてあるのでしょうか?
今の僕には理解できない

アバター
MoNoQLoREATOR
記事: 284
登録日時: 14年前
住所: 東京

Re: 線分と円の重なり判定

投稿記事 by MoNoQLoREATOR » 12年前

”重なる”という概念は3次元以上でしか有り得ないと思いますよ?
奥ゆきがなければ重なることはできないはずです。
平面同士がすり抜け合うことができる世界であればもしかしたら…いや、それは重なっていると言うのでしょうか?

アバター
みけCAT
記事: 6734
登録日時: 14年前

Re: 線分と円の重なり判定

投稿記事 by みけCAT » 12年前

なるほど。
そう考えると3次元の接触が謎ですね。
「重なって」いるだけでは接触していないのではないでしょうか?
円(円盤)が傾いていればOKかもしれませんが。