スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
以後の更新内容の改善のために、是非ともご評価のほどよろしくお願いします!→

円同士の当たり判定【C言語での実装】

2Dアクション開発記録 は累計で第5弾になりました。このシリーズの前回の記事「円同士の当たり判定」では概念の説明だけでしたが、今回は実際にプログラミングで実装してみたいと思います。


円と円が接触または部分包括した場合に真を返す関数を作りました。
今回は外積だのなんだのという小難しいものは出てきません。せいぜいピタゴラスの定理(三平方の定理)くらいです。ただ、この記事ではプログラムしか提示しません。考え方は上で紹介した記事(こちら)をご覧ください。



円同士の当たり判定のテスト(C言語(C++?))



描画自体はDXライブラリという便利なものを使うので簡単です。一番重要なのはCircle構造体の定義内容と関数CollisionCCだけです。

円と円の当たり判定をおこなうCollisionCC関数に、判定したい2つのCircle型構造体を(引数として)渡してやれば判定をおこなってくれます。当たっていればBOOL型のTRUE、当たっていなければFALSEを返します。(接している場合も“当たっている”と判定します。)
(ちなみにCollisionCCの「Collision」は「衝突」の意味です。「CC」はCircle&Circleという意味です^^;)

ちなみにテスト環境は、Microsoft Visual C++ 2008 ExpressEdition です。



概念は前回の記事(こちら)で説明したといいましたが、超簡単にですが説明しておきます。

2つの円が接している状態を考えたとき、それぞれの円の半径を足したもの(以下、Rとする。)2円の中心点距離(以下、Dとする。)は等しい状態です。次に部分包括している状態(2円の一部が重なっている状態)ではRよりDのほうが小さくなります。逆に2円が離れている状態(当たっていない状態)では、RよりDのほうが大きくなります。
この性質から、DR以下のときに当たっていると判定できることがわかります。
その際、平方根の計算が含まれると処理が重くなるので、条件式の両辺を二乗したものを判定式として使い、CollisionCC関数を定義しました。

アクションゲームなら、自キャラと敵キャラの当たり判定などにも使いそうですね。



はたして、こんな説明でわかってもらえたのでしょうか・・・(説明が下手でゴメンナサイ...^ ^;)

円同士の当たり判定(当たっていない)円同士の当たり判定(当たっている)
当たっていない場合は「0」当たっている場合は「1」
Cキーを押すと半径が大きくなるXキーを押すと半径が小さくなる
Cキー押下で半径増Xキー押下で半径減
方向キー(矢印のキー)で円を移動させることが出来ます。

というわけで、上のプログラムをサンプルプログラムとして置いておきます。当たり判定が出来ていることを確かめてみてくださいね。(ご使用の環境によっては動作しない場合もあります。少なくともWindowsで動かしてください^^;)


【お試しダウンロード】(約1.06MB)

ってか、この程度のプログラムでなぜこんなに容量を食うのかな・・・(汗)
スポンサーサイト
以後の更新内容の改善のために、是非ともご評価のほどよろしくお願いします!→

テーマ : プログラミング /  ジャンル : コンピュータ

円同士の当たり判定

最近「円と円の当たり判定」で検索して来てくださる方がいらっしゃったんですが、残念ながらまだ用意できていませんでした。なので、この機会に当たり判定について(自分の頭の中の知識を整理することを目的に)書いておきます。

さて、今回は円同士(円と円)の当たり判定です。

実はこの判定は比較的カンタンです。理解してしまえばどうということはありません。
(ちなみに、それぞれの円について中心座標(x,y)と半径rがわかっていればOKです。)


(※この記事では、「円同士の当たり判定」の概念を説明しているだけで、プログラム例は掲載していません。そこでC言語(C++)での実装例を紹介する記事もこしらえましたので参考までにご覧くださいませ。「円同士の当たり判定【C言語での実装】」)


図1を見てください。このように2つの円があったとします。(左下が円A、右上が円Bとします。)

図1

x1、y1は円Aの中心点の座標です。どこを基準にとっても問題ではありません。x2、y2は円Bの中心座標です。また、それぞれの円の半径r1、r2がわかっているものとします。
また、判定処理のときには、r1とr2の距離が必要になってきますが、これは上に出てきた数値で求めることになります。



さて、この2つの円が当たっているのかどうかを判定する訳ですが、その前にまず2つの円が接する状態を見てみましょう。

図2:接する状態

2つの円が接していますね。ここで注目すべきは円Aと円Bの中心座標同士の距離dです。見ればわかりますが、r1とr2を合わせた距離「r1 + r2」と中心座標同士の距離「d」が等しいですね?

式で表せば「r1 + r2 = d」となりますが、これぞ円同士が接する判定条件です。この式が成り立てば2つの円が接していることがわかります。

しかし、ゲームでの当たり判定は接している場合だけではありません。互いの一部分が重なり合っている場合も「当たっている」と判定しなければなりません。さて、どうしましょう...


次に、円の一部が重なっている状態の図を見てみましょう。

図3:一部が含まれる状態

r1とr2を一直線上においていないのはわざとです。どうですか?r1とr2を足したものと距離dを比べてください。明らかに半径同士の合計(和)の方が大きいですね。

このことから、「r1 + r2 > d」という式が得られます。この条件式を満たす場合は円の一部分が重なっているということがわかります。(ただし、接しているときは含まれません。



要するに、実際に条件式として用いる場合は上の二つの場合をどちらも含めて次のようにします。

円同士が当たる条件

この条件式が成り立つときに、2つの円が「当たっている」と言えるのです。





さて、判定の概念がわかったところですが、実際に判定させるには距離dを算出しなければなりません。
(求め方がわかる人は読む必要はないでしょう。)

図4:ピタゴラスの定理(三平方の定理)

ここでは上図のピタゴラスの定理(三平方の定理)を利用して距離dを求めます。

図5:距離dの求め方

この図は円の中心同士を結んだ線を斜辺とする直角三角形を考えたものです。
この直角三角形でピタゴラスの定理を考えると、斜辺(距離d)を求めるわけですから、直角三角形の底辺と高さがわかれば良いわけです。
2つの円のx,y座標をそれぞれ引いたものの絶対値は、その長さになりますから、
底辺は「 |x1-x2| 」、高さは「 |y1-y2| 」となります。

あとはピタゴラスの定理の式からいろいろ変形していけば式を導くことが出来ます。

図6:式の変形
1行目はピタゴラスの定理です。
2行目は...言葉で説明しづらいですね・・・、cについて二乗から一乗に変形しています。
3行目はcは斜辺の長さなので負の数にはなりません。(だから「?」を取り除く。)
cは斜辺(すなわち2つの円の中心座標の距離d)なのでdに変えてしまい、先ほど求めた直角三角形の高さと底辺をa,bそれぞれに代入して4行目の式になります。
絶対値記号「|」がついているので、なんとなく展開して再度、因数分解します。(6行目)


このように求めた距離dを用いて、最終的には次のように変形します。

図7:最終的な変形

1行目は2つの円が当たる条件式です。
2行目はdに先ほど求めた式を代入したものです。

別にこの状態で条件判定を行ってもいいのですが、コンピュータの計算処理的に平方根(ここではルート)の計算は結構大変なんだそうです。(想像つきますよね^^;)
なので、ここでは両辺の平方をとります。(両辺を2乗する。)
そうすれば赤枠の式が求まり、(少なくとも平方根を含んだ計算より遥かに?)軽い「当たり判定」が行えるはずです。(たぶん。)





これだけ長々と説明しても、結局これを理解してくれる人は(説明が下手すぎて)非常に少ないだろうなと思いつつ、この締めの文を打ち込んでいます。時間を使った割には実のない説明となりました(うぅ...残念--;)

もし「そりゃ違うだろっ!」という具合の間違い等がございましたら是非ご指摘ください。(間違えたまま覚えてしまうと困るので。)
あと、間違えていたらゴメンナサイ・・・(汗) 今日はここで失礼します。m(_ _;)m



(※この記事の先頭でも紹介しましたが、この判定概念を実際にプログラムに実装してみた記事を掲載しております。「円同士の当たり判定【C言語での実装】」参考になれば幸いです^^)
以後の更新内容の改善のために、是非ともご評価のほどよろしくお願いします!→

ある点が、線分を境にどちらに存在するか

2Dアクション開発記録 第3弾は、外積を使ったテクニックを紹介します。


今回は、「ある点が、線分を境にどちらに存在するか」を判定する関数を作りました。


ちなみに、参考にしたサイトは下のサイトです。
○×つくろーどっとコム: 内積と外積の使い方:【外積の概念とその利用を学びました】

恥ずかしながら、私はゆとり教育世代なので、高校数学Bのベクトルでは外積を習いませんでした。なので、上のサイトで調べてから自校の物理の先生に質問しに行って、なんとなく理解しました。


今回の関数は、外積の(成分のほうの)公式を使っているだけなので難しくありませんが、
数学のY座標と、ウィンドウのY座標が正反対なので、ほんの少し手こずりました。


(外積を使った)線分と円のテスト(C言語(C++?))



内積を使った当たり判定と同様に、DXライブラリというものを使うので、描画自体は簡単です。

PositionLC関数が判定関数で、中心点が線分の上ならTRUE、下ならFALSEが返されます。 (PositionLCの「LC」は、Line&Circleという意味です^^;)
ちなみに、コンパイル等は、Microsoft Visual C++ 2008 ExpressEdition を使用。



超簡単に説明します。(この文は、ZIP内のReadme.txtに記述されています。)

線分ベクトルの成分と、線分の始点から円の中心までのベクトル成分を元にした
外積計算の結果から判定します。線分ベクトル成分を(Ax,Ay)、円中心へのベクトル成分
を(Bx,By)としたら、外積は「Ax×By?Bx×Ay」ですが、数学上のY軸とウィンドウのY軸は、
方向が正反対なので、計算式を「Bx×Ay?Ax×By」としてやりました。
その外積の値が正の数なら、線分より上に点が存在し、逆に負の数なら、線分より下に
点が存在することになります。

わかりづらい説明ですがお許しを(汗)

ある点が、線分を境にどちらに存在するかの判定

【お試しダウンロード】(約530KB)



これを使えば、キャラクターが線上に上手く乗ってくれる処理が実現できるようです。

数学って便利ですね・・・


(追記:プログラム中に致命的なミスを含めていたことがわかりましたので訂正させていただきます。申し訳ありません...(2009.10.13)) (追記:プログラム中にBOOL型を使用していましたが、これはC++での対応となり、標準のC言語では対応しておりませんでした。不備が重なり申し訳ありません。(2009.10.14))
以後の更新内容の改善のために、是非ともご評価のほどよろしくお願いします!→

テーマ : C言語 /  ジャンル : コンピュータ

線分と円の当たり判定関数

さて、C言語(厳密にはC++?)で作る2Dアクションゲーム開発記録 第2弾となりました。


今回は、ちょっと頭を悩ませて「線分と円の当たり判定(衝突判定)」を行う関数を作りました。
(この記事は前記事にて報告のミスを訂正したものです。)

Googleで「線分 円 当たり判定」で検索しても、あまり出てこなかったので割と苦労しました。
しかし、何とかそれに近いサイトが見つかったのでそちらもご紹介。
X-LABO: 円と線分の交差判定:【線分と円の衝突判定概念を学びました】
○×つくろーどっとコム: 内積と外積の使い方:【内積の概念とその利用を学びました】

高校数学Bのベクトルの概念が役に立つとは思いもしませんでした。
履修してて良かった・・・・(^ ^;)



早速、その関数の紹介。
ちなみに、(効率悪いですが)平方根の計算が含まれるので、math.hをインクルードして使用します。


線分と円の当たり判定を使ったテスト(C言語(C++?))



DXライブラリという便利なものを使うので、描画自体は難しいことではありません。

CollisionLC関数が当たり判定の関数で、接触していたらTRUE、非接触ならFALSEが返されます。 (CollisionLCの「LC」は、Line&Circleという意味です^^;)
ちなみに、コンパイル等は、Microsoft Visual C++ 2008 ExpressEdition を使用。



また、この関数の概念については、また時間が空いたときに解説したいと思います。
(半分近くは、上で紹介したサイトと同じやり方です。)



線分と円の当たり判定

【お試しダウンロード】(約530KB)



衝突しているか否かがわかれば、あとはそれを応用して壁と認識させれば良いわけで・・・
それがまた時間がかかるんだろうなぁ・・・


とりあえず、大きな進歩でした。


(追記:プログラム中にBOOL型を使用していますが、これはC++での対応となり、標準のC言語では対応しておりませんでした。訂正させていただきます。(2009.10.14))
以後の更新内容の改善のために、是非ともご評価のほどよろしくお願いします!→

テーマ : C言語 /  ジャンル : コンピュータ

掲載内容の不備について【線分と円の当たり判定】

 先日、当サイトでご紹介した「線分と円の当たり判定」の記事ですが、
大変重大なミスがありましたので、掲載を中断します。

その代替となる記事をご用意しておりますのでお手数ですがそちらをご覧ください。

【線分と円の当たり判定関数】←こちらです。

ご迷惑をおかけしますことをお許しください。
以後の更新内容の改善のために、是非ともご評価のほどよろしくお願いします!→
カテゴリー
ようこそ!
Author: Torasuke
Profile: 地元大学の情報系学部に息をひそめる二回生。
   SA SW


ブログ内検索
最近のコメント
オススメ
京都の大学生のラボブログ
Python,Java,Objective-C,GAE,Macなど
Python独習中の大学生のブログ


ltzz.info
ここの管理者さんには謁見済み!(えっ

 Use OpenOffice.org
無補償でも良いなら、MSOfficeよりOpenOfficeで十分です。

Mozilla Firefox ブラウザ無料ダウンロード
当サイトは、Firefoxというブラウザで動作確認しています。私は以前、IE派でしたが、一度乗り換えて慣れてしまうと、Firefoxのほうが便利だということを実感しました。

是非よろしくお願いします。
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。