A 回答 (10件)
- 最新から表示
- 回答順に表示
No.10
- 回答日時:
#7 です。
遅くなりましたが補足します。
> 判定関数が内部でどのように判定しているのか、
> を知りたいと思っています。
Adobe(Macromedia)の社員でもプログラマでもないので,
そのアルゴリズムはわかりませんが,
当たり判定をするときのアルゴリズムは,おそらく,見たそのままのアルゴリズムだと思いますよ。
つまり,
内積とか外積とか角度とかそういう計算は内部でしていないと思います。
「オブジェクトに面を持たせて,
その面が点と接触しているかしていないかを判定している。」
つまり,見たそのまんまです。
オブジェクトに面を持たせるときには複雑な計算もさせている部分もあると思います(例:面を閉じるとかいうアルゴリズム)。
しかしいったん面を作成してしまったあとは,その面と接触しているかしていないかです。
たとえば背景と面との色を比べても良いと思います。
つまり点がある場所の背景色を get して,
FFFFFF だったらハズレ,00FFFF だったらアタリ。
色がダメでしたら,色とは別の1ビットのプロパティを与えても良いと思います。
そのような演算をしていると思います。
なぜそう思うかと言うと,
#7 ではプログラムによって面を作図しましたが,実際そんなことはまずしません。
適当に描いた絵やラフな手描きの絵(と言ってもベクトルデータ(ミサイルとかゴジラとか))で当たり判定をとるのが普通です。
その図形を一々方程式に変換して,その方程式で当たり判定をとるなどということはナンセンスです。
してできなくはないと思いますが,おそらくその演算でアニメーションが止まります。
ActinScript は直接関係ないとはわかっていましたが,
そう言った意味を含めて #7 を書かせていただきました次第です。
No.9
- 回答日時:
あ!下のやつは星型で手詰まりますね。
もう一工夫いります。それと、もっといい方法がありました。完全に閉じている訳ですからx=aの直線で貫いた場合、[ P_i+1 - P_i ]区間内に交点が存在する線分が偶数個あるはずです。それをy軸の値が大きい順にソートすれば、[y0-y1][y2-y3]・・・[y_2m-1,y_2m]が区間内を表します。この区間内にbが入っていれば、(a,b)は領域内になります。ただ、y軸と平行な線分にぶつかった場合の特殊処理を忘れずに。この方法なら多面体の内点判定も楽勝ですな。恐らくコレが最強かと・・・。以前、この方法でレイトレーシングの交差判定やったのスッカリ忘れてました・・・。発想次第でこれだけスピードが変わるというのを試してみると面白いですよ。自分の時は3角形の内点判定が複数個って感じで大きな速度差が出てました・・・。お試しあれ。
No.8
- 回答日時:
>第一段階の、凸な多面体になるまで分割、とあるので、このアルゴリ
>ズムを考えないといけませんが、すぐに思いつきませんでした。
ではでは、補足です。真の第一段階は、
>n個の点は(x1,y1)-(x2,y2)-…-(xn,yn)とします。
>(xn,yn)と(x1,y1)を最後につないで閉じた多角形とします。
この順序を自動的に確定する所なんですが、それは定まっているものとして話を進めます。次は以下のベクトルの外積を使い、トレースしつつ
凸な多角形(こう言うんだ・・・)を切り出していきます。(x1,y1)-(x2,y2)-…-(xn,yn)は循環リスト構造にしとくとよいよ。
まず、
vf_n=(x_n+1-x_n,y_n+1-y_n,0)
vb_n=(x_n-x_n-1,y_n-y_n-1,0)
を定義します。(_以降は表記の都合上、添え字を表す事にします。f,bはフォワードとバック)
これも同様にvfnとvbnの外積のz成分の符号で内角が180度超えの分割すべき点かどうかを順々に判断していきます。一つも無ければハッピーで次の内点判定に進んで下さい。手順は以下の通りです。
i=1~nまで繰り返す(ここでnは元の循環参照リストの要素数を表す事に注意。循環参照リストの要素数は除外されていくので可変の値である)
mfg=false、i=1、k=0を初期状態として始める。
1).vf_iとvb_iの外積計算を行う。
2).内角180以下であればiをインクリメントし1).へ
内角180より大きければであれば3).へ
3).マークポイント保持フラグmfgがfalseであれば4).へ
マークポイント保持フラグmfgがtrueであれば5).へ
4).マークポイント保持フラグmfgをtrueに設定し、マークポイント指数kにiの値を設定し1).へ
5).vfmpとvb_iの外積を計算する。ここで、
vfmp=(x_k-x_i,y_k-y_i,0)
とする。
6).この結果が内角180より大きければkをインクリメントし5).へ
内角180以下なら7).へ進みます。
7).P_kからP_iまでを凸多角形領域として新たに循環参照リストを生成します。これはもういじらない。
8).P_k+1からP_i-1を元の循環参照リストから除外します。
9).mfgをfalse、iを1、kを0と初期化し1).へ
i>nの時点で処理が終了。
ここで終了時に状態が二つある事に注意。mfg=falseで終了する場合と、mfg=trueで終了する場合である。前者は内角180を越える点が存在しなかった場合である。それ以外は後者となり、更に一回分割の必要を残したまま終了する。
その分割は、新たにベクトル
vlf=(x_k+1-x_k,y_k+1-y_k)
vbf=(x_k-1-x_k,y_k-1-y_k)
を定義し、vlf+vbfで生成されるベクトルで点P_kを通る直線に最も近い循環参照リスト上の点をP_sとする。s>k、s<kを気にしつつ領域を除外。P_kが内角180以下であれば終了。180よりで大きければもう一回で終了です。
多分これで全ての場合で凸領域に分割できるはず。思いつきだからあまり巧くないですが・・・。外積は安易な方法なので、パフォーマンスに関して更に上があるかもしれません。考えてみて下さい。
例えば、浮動少数値でなくていいなら、Zバッファの様な方式の方がレスポンスは良い。ただ、パフォーマンスと使用メモリがトレードオフになってしまいます。とかみたいに。
文章に起こすの超大変でした。
以上、参考にして下さいね。
No.7
- 回答日時:
他の方も書かれていらっしゃいますが,
まずご質問の言語がわかりません。
ご質問の言語が もし,
「2次元平面を持つオブジェクト(インスタンス)が作成できるような言語」
でしたら,
多角形の線で区切られた平面 を持つ オブジェクト を作成して,
そのオブジェクトと点との座標接触判定をすれば簡単ではないかと思います。
最初から考えることに比べると反則的なことかもしれませんが...。
多角形の辺で囲まれた中にあるとかないというような座標で全てを考えるのではなくて,
オブジェクト(インスタンス)というものを利用するということです。
#3 の方の書かれていらっしゃいますが,
Flash(ActionScript) には当たり判定メソッド(MovieClip.hitTest メソッド)があります。
※ActionScript は
Adobe Flash というソフトでなくても使用できます。
ご質問の言語は ActionScript ではないとは思いますが,
この ActionScript を用いた例を書くと以下のようになります。
多角形の作図から判定まで,
すべてを ActionScript でしてしまうコードです(本当に動作する例)。
----------------------------------------------
// 座標データ格納配列の作成
crdArr = new Array();
// 各 xy座標をハッシュで代入(データは適当)
crdArr.push({x:40, y:30});
crdArr.push({x:100, y:40});
crdArr.push({x:130, y:90});
crdArr.push({x:90, y:110});
crdArr.push({x:90, y:150});
crdArr.push({x:30, y:120});
crdArr.push({x:30, y:90});
crdArr.push({x:70, y:110});
crdArr.push({x:90, y:80});
// 多角形描画用ムービークリップを深度 0 に作成
this.createEmptyMovieClip("polygon", 0);
// ムービークリップの中に多角形の塗りを描画
polygon.beginFill(0x00FFFF, 100);
polygon.moveTo(crdArr[0].x, crdArr[0].y);
for (i=1; i<crdArr.length; i++) {
polygon.lineTo(crdArr[i].x, crdArr[i].y);
}
polygon.endFill();
// 判定結果表示用テキストフィールドを作成
this.createTextField("judge_txt", 1, 150, 30, 0, 0);
judge_txt.autoSize = true;
// 任意の場所でマウスダウンしたときの動作
this.onMouseDown = function() {
judge_txt.text = "座標 ("+_xmouse+", "+_ymouse+") は";
if (polygon.hitTest(_xmouse, _ymouse, true)) {
judge_txt.text += "\n多角形内にあります。 ○";
} else {
judge_txt.text += "\n多角形内にありません。 ×";
}
};
----------------------------------------------
動作検証を簡単にするため,
Flash上をクリックしたときのマウスの座標が多角形と当たっているかどうかを調べていますが,
特にマウスの座標でなくてもかまいません。
オブジェクト.hitTest(任意x座標, 任意y座標, true)
これで true か false の戻り値を得ることができるので,
多角形オブジェクトが任意の x座標 y座標 と当たっているかどうかが調べられます。
(シューティングゲームにはこの hitTestメソッド を使ったものが多いです。)
上記スクリプトコードを書いて作成できるのは Flash です。
しかし簡単な ActionScript だけですから,
上にも書きました通り少しだけ高度な ActionScript が使えるソフトであれば,
Adobe Flash を使う必要は全くありません。
例えば フリー の Flash作成ソフト ParaFla! や Suzuka でも,
十分作成できます。
・ParaFla!
http://www.geocities.jp/coa9999/
・Suzuka
http://www.cty-net.ne.jp/~uzgensho/
・ParaFla! であれば
ParaFla! をインストール(DL&解凍)して ParaFla! を起動。
フレーム1 となっている部分を右クリック→「アクションを挿入」。
出てくる イベントのプロパティ パネル でアクションの設定を <スクリプト> にする。
「スクリプトを編集」ボタンをクリックしてスクリプトエディタを出し,
そこに上記スクリプトをコピペ。
「適用」ボタンを押してスクリプトエディタを閉じ,
[プレビュー]→[プレビューウィンドウ] で動作確認できます。
・Suzuka であれば
Suzuka をインストール(DL&解凍)して Suzuka を起動。
上部左にある □背景 となっているレイヤーを選択して,
右クリック→アクションレイヤーの挿入 で「フレームアクション」のレイヤーを挿入。
その右の タイムライン の フレーム1 を選択し,
画面右下の「スクリプトを編集」ボタンをクリックしてスクリプトエディタを出して,
そこに上記スクリプトをコピペ。
[ウィンドウ]→[プレビュー] で動作確認できます。
座標は適当だと言っても,一応辺どうしの交差はないようにはしてあります。
上スクリプトの座標の場合だと,
だいたい次のような形の多角形が自動描画されますが,
□□□□□□□□□□□□
□□■■■□□□□□□□
□□□■■■■■■□□□
□□□□□■■■■■□□
□□□□□□□■■■■□
□■□□□□■■■■□□
□■■■□■■■■□□□
□□■■■■■■□□□□
□□□□□■■■□□□□
□□□□□□□■□□□□
□□□□□□□□□□□□
■の(実際は 水色00FFFF に塗られる)部分でマウスダウンすると,
その座標と 多角形内にあります。 ○ が表示されます。
□の(実際は何もない部分)部分でマウスダウンすると,
その座標と 多角形内にありません。 × が表示されます。
Flashは使い方によって,
このように図形演算ソフト(道具)としても使えることもあります。
Flash は元が図形と図形のアニメーションソフトですから,
このようなものの場合(場合によります),
例えば Excel (VBA や ワークシート関数)などでプログラミングするよりはるかに簡単かもしれません。
以上,
ご質問の言語は ActionScript ではないことは推測できますが,
「2次元平面を持つオブジェクト(インスタンス)が作成できるような言語」であると,
場合によっては非常に簡単にできることもあるという参考例です。
別の回答にも書きましたが、あえて言語を書くならばC言語です。
ActionScriptは使用したことがありませんが、記述していただいたプログラムの内容は理解できます。しかし、判定関数が内部でどのように判定しているのか、を知りたいと思っています。もしご存知でしたらよろしくお願いいたします。
ありがとうございました。
No.6
- 回答日時:
もし内角が180度を超える点がある場合は、それが発生しない多角形
となるまで分割します。この処理を一段かませます。これがミソ。
その後の多角形の各座標が(x1,y1)-(x2,y2)-…-(xn,yn)、任意の点が
(a,b)であるとして、以下ベクトルを定義します。都合上3次元ベクト
ルとします。
v1=(x2-x1,y2-y1,0),vp1=(a-x1,b-y1,0)
v2=(x3-x2,y3-y2,0),vp2=(a-x2,b-y2,0)
v3=(x4-x3,y4-y3,0),vp3=(a-x3,b-y3,0)
・・・
vn=(x1-xn,y1-yn,0),vpn=(a-xn,b-yn,0)
このviとvpiの外積をそれぞれ求め,その結果のzベクトル成分が全て同
一符号であった場合のみ、内点です。言い換えるなら、
k1=(x2-x1)*(b-y1)-(y2-y1)*(a-x1)
k2=(x3-x2)*(b-y2)-(y3-y2)*(a-x2)
k3=(x4-x3)*(b-y3)-(y4-y3)*(a-x3)
・・・
kn=(x1-xn)*(b-yn)-(y1-yn)*(a-xn)
の全てのkが同一符号であれば良いということになります。注意すべき
点としてP1、P2、・・・とたどっていく順序が右回り・左回りの夫々で
正負が逆転します。必ずどちらかとなる様に定義しプログラミングして
下さい。また、線上に(a,b)がある場合、ki=0となる状況が1つだけ
存在します。線上は内点とした方が良い(上の分割境界上の時)為、0以
上、0以下と判定してください。
コレを分割領域全てにおいて計算し、内点との判定が出た時点でbreak
します。どういうプログラムを書くべきか見えてきましたね?
余裕があったら、応用として多面体の内点を判定する方法を考えてみて
ください。かなり頭の体操になりますよ。
数学的にエレガントな回答だと思います。
第一段階の、凸な多面体になるまで分割、とあるので、このアルゴリズムを考えないといけませんが、すぐに思いつきませんでした。
多面体への応用としては、面の法線ベクトルと、判定すべき点と面の頂点を結ぶベクトルとのなす角度を調べれば‥‥などと考えましたが、ひょっとして外積を4次元に拡張するとか。。。
ありがとうございました。
No.5
- 回答日時:
解法の考え方の一つとしてですが。
必ず多角形の外側になる点 (a',b') を設定します。
具体的には、次の4つの内いずれかの条件を満たす点です。
a'>Xmax
a'<Xmin
b'>Ymax
b'<Ymin
この (a',b') と (a,b) を結ぶ直線を引きます。
線 (a,b)-(a',b') と多角形の辺との交点の数が奇数なら内側、偶数 (当然、0も含みます。) なら外側となります。
確かに判定できそうです。
(a',b') と (a,b) は、a'=a または b'=b となるように取ると計算がより楽になりそうな気がします。
ありがとうございました。
No.4
- 回答日時:
考え方です
まず、角(xi,yi)(a,b)(xi+1、yi+1)の角度を-πからπの範囲(-180度から+180度でもいいです)で求めます。大切なのは、(xi,yi)(a,b)(xi+1、yi+1)の方向を常に決めておくことで、前の点iに対して左回りになっていればプラス、右回りであればマイナスとします。
これをi=1~nまで繰り返し(i=nでは、nをi+1とします)、その総和を求めて2πになれば内側、0になれば外側です。計算誤差が出てぴったりにはならないのでその辺は判定してください。
同様に角度の代わりとして三角形(xi,yi)(a,b)(xi+1、yi+1)の面積をヘロンの公式で求め、方向に応じて加減していけば一周すると内側なら面積、外側なら0になります。こちらの方が使い勝手がよいかも(これはちょっと記憶が怪しい)
点が辺上に来た場合や頂点上の場合の別判定はしてください。
S=(1/2)ab sin(C)、S:面積、a b:辺の長さ、C:角Cの大きさ
の公式で角度または方向を求めることになると思いますので、前者と後者はほぼ同じだと思います。
理論上、外部にあれば0になりますが、丸め誤差で0にならなかった場合に辺上にあるかどうかを毎回別判定しなければならなくなるのではないかという懸念が若干あります。
ありがとうございました。
No.3
- 回答日時:
お使いの言語は何なのでしょうか?
使ったことはないので、知識だけなのですが、Delphiには多角形の交差判定の関数があったと思います。(Flashでもあったかな?うろ覚え。
Win32APIでも、あったような。
とりあえず、CombineRgnは見つかりましたが。
http://www.geocities.jp/asumaroyuumaro/program/w …
これって、うまく使えないんですかね?
ゲームは、いつか作っては見たくて、それらしいものをスクラップはしているのですが。
言語はC言語を想定しています。
アルゴリズムについての質問ですので、
判定関数を用いることは想定していません。
もしくは、判定関数があるとしたら、その中では
どのようなアルゴリズムになっているのかを知りたいと思っています。
ありがとうございました。
No.2
- 回答日時:
辺の方程式と定義域のリストを作成して、
ターゲットの点との上下関係から求めるという方法ですね。
直感的で分かりやすいです。
直線の式を求めるところで計算量が増えそうな点が若干心配ですね。
ありがとうございました。
No.1
- 回答日時:
単なる思い付きですが・・・
1)点(a,b)と多角形の1点Xを結ぶ線分を考える
2)上記線分が多角形のすべての辺と交わらないかチェック。
交わる辺が存在するなら、点(a,b)は多角形の外部にある
(三角形で考えてみてください)
3)多角形のすべての点について、2)のチェックを繰り返す
4)3)のチェックで交わる辺が存在しないならば、点(a,b)は
多角形の内部に存在する
2つの線分が交わるかどうかのチェック方法はこちら。
http://www.deqnotes.net/acmicpc/2d_geometry/lines
・・・と、ここまで考えて、上記の方法は多角形の内閣が180度を超えるものが存在する場合は
使えないことに気がつきました。
(星形みたいなギザギザの奴)
うーん。もうちょっと検討が必要ですね。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# ある線が円の範囲に入っているかの計算 1 2022/12/07 16:14
- 高校 数学Aの問題で、円に内接するN角形(N>4)の対角線の総数は ア 本である。また、Fの頂点三つからで 1 2023/04/13 17:47
- 数学 『弧は弦より長し』 8 2022/04/18 10:23
- 数学 サーケーリ・ルジャンドルの第2定理 4 2022/08/30 16:41
- 数学 複素数平面についての問題です。 2点α、βが定められており、それらともう1点γと結ぶ三角形が直角二等 6 2023/06/30 09:47
- 数学 AB=2,BC=3,∠ABC=60°の三角形がある。 点Aから辺BCに垂線を下ろし辺BCとの交点をD 4 2023/02/02 15:55
- Excel(エクセル) エクセルで同じ数字同士を自動で線で結ぶVBAを教えてください 6 2022/04/26 23:13
- 数学 写真の図は中心(a,b)半径rの円とその円周上の(x1,y1)における接線lと円の中心とlを結ぶ任意 4 2023/08/08 16:20
- 数学 数学直線の方程式とベクトル方程式について 直線の方程式で 点(x1,y1)を通り、直線ax+by+c 1 2022/08/12 12:13
- 数学 問題文 正n角形がある(nは3以上の整数)。この正n角形のn個の頂点のうちの3個を頂点とする三角形に 4 2023/03/22 14:57
このQ&Aを見た人はこんなQ&Aも見ています
-
それもChatGPT!?と驚いた使用方法を教えてください
仕事やプライベートでも利用が浸透してきたChatGPTですが、こんなときに使うの!!?とびっくりしたり、これは画期的な有効活用だ!とうなった事例があれば教えてください!
-
スマホに会話を聞かれているな!?と思ったことありますか?
スマートフォンで検索はしてないのに、友達と話していた製品の広告が直後に出てきたりすることってありませんか? こんな感じでスマホに会話を聞かれているかも!?と思ったエピソードってありますか?
-
【お題】逆襲の桃太郎
【大喜利】桃太郎が1回鬼退治に失敗したところから始まる新作昔話「リベンジオブ桃太郎」にはこんなシーンがある
-
この人頭いいなと思ったエピソード
一緒にいたときに「この人頭いいな」と思ったエピソードを教えてください
-
今から楽しみな予定はありますか?
いよいよ2025年が始まりました。皆さんには、今から楽しみにしている予定はありますか?
-
エクセルで出来るのかを教えてください
Excel(エクセル)
-
座標を持った平面範囲に座標を持った線分が入っているかを判断する方法
計算機科学
-
閉図形の座標の配列が右回りか左回りか調べる方法
Visual Basic(VBA)
-
-
4
空間上の二点を結ぶ直線上に任意の点が存在するかどうかの関数
C言語・C++・C#
-
5
傾いた四角形内の範囲の条件式
Visual Basic(VBA)
-
6
3次元の平面上の点かどうかを判定したい
数学
-
7
多角形の中心点の座標の求め方
数学
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・「みんな教えて! 選手権!!」開催のお知らせ
- ・漫画をレンタルでお得に読める!
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・【選手権お題その3】この画像で一言【大喜利】
- ・【お題】逆襲の桃太郎
- ・自分独自の健康法はある?
- ・最強の防寒、あったか術を教えてください!
- ・【大喜利】【投稿~1/9】 忍者がやってるYouTubeが炎上してしまった理由
- ・歳とったな〜〜と思ったことは?
- ・ちょっと先の未来クイズ第6問
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・【選手権お題その2】この漫画の2コマ目を考えてください
- ・【選手権お題その1】これってもしかして自分だけかもしれないな…と思うあるあるを教えてください
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
マインクラフト(pc版)で座標...
-
グラフの交点の求め方(Excel)
-
一番近い点を見つけたい。
-
3次元空間上の2つの座標から...
-
エクセルである点からの距離で...
-
黒体放射軌跡のxy色度座標への...
-
エクセルシート上のマウスポイ...
-
抽出した特徴点の座標を取得し...
-
3次元座標上の2直線の交点判...
-
日本国内の、アクセス地域によ...
-
DirectXを使ってテクスチャ(画...
-
凸型の多角形の座標
-
ガウシアンフィルタのCプログラム
-
変数名のこだわりについて
-
Minecraft 統合版(PC)の描画距...
-
コントロールの書式設定で、“コ...
-
エクセルで作った新しいウイン...
-
vbaから他のアプリを終了
-
word
-
エクセルのコントロールツール...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
グラフの交点の求め方(Excel)
-
マインクラフト(pc版)で座標...
-
3次元空間上の2つの座標から...
-
ダイアログ内コントロールの位...
-
エクセルで回転する座標の出し方
-
シーケンサー(PLC?)で制...
-
エクセルである点からの距離で...
-
始点、終点の二つの座標と半径...
-
C言語 配列で座標
-
多角形の内部かどうか判定する方法
-
閉図形の座標の配列が右回りか...
-
以下のプログラムは重心を求め...
-
c言語でキーボードから2点の座...
-
Excel VBA で自在に図形を変化...
-
タッチパッドのタッチ座標取得
-
C言語において、0の座標をキャ...
-
当たり判定後に面に沿って動か...
-
ワード上Shapeの位置情報を統一...
-
黒体放射軌跡のxy色度座標への...
-
一番近い点を見つけたい。
おすすめ情報