c++ 玉の反射について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
calbee
記事: 10
登録日時: 3年前

c++ 玉の反射について

#1

投稿記事 by calbee » 3年前

現在タイマーを使って、斜め方向に進む2つの玉が、四方の壁に当たると反射するというものができています。2つの玉が衝突したときに跳ね返って、進行方向が変わるようにしたいのですが、やり方が分からないです…どのように書けば良いのでしょうか…?

アバター
usao
記事: 1887
登録日時: 11年前

Re: c++ 玉の反射について

#2

投稿記事 by usao » 3年前

最も手っ取り早い(しかし,しょぼい,ごまかし的な)方法の1つとして,2つの弾の速度を入れ替えるというものがある.

衝突してきた相手の移動方向や速さに応じたそれっぽい挙動を示したいなら,
おそらく物理的な話を持ち込む必要がある.

calbee
記事: 10
登録日時: 3年前

Re: c++ 玉の反射について

#3

投稿記事 by calbee » 3年前

コード:

  
if(x==x1 && y==y1) {
  a=dx;
  dx=dx1;
  dx1=a;
  b=dy;
  dy=dy1;
  dy1=b;
}
x,y x1,y1というのが2つの玉の座標で、dx,dy dx1,dy1が速度です。
これで衝突時(同座標)に速度を入れ替えたつもりなんですが、上手くいかないです…
やり方が違うのでしょうか…?

アバター
usao
記事: 1887
登録日時: 11年前

Re: c++ 玉の反射について

#4

投稿記事 by usao » 3年前

「やったつもりだけど上手くいかない」と言われましても,何が何だかわからんです.

【「やり方」が合っているか否か】というのは,あなたが実装しているプログラムに依存する話です.

例えば,「玉」と言われたら,私は「ある程度大きさを有する(丸い)物」を想像しますが,
そのコードを見た感じ,サイズという概念の無い「質点」のような扱いが成されているように見えます.
そのことが,あなたのプログラムの仕様の上で正しいのか正しくないのかは,私にはわかりません.

また,外野からすれば,自由に運動する何かの衝突判定として,

> x==x1 && y==y1

なる(「座標の完全一致」という)条件を満たすことは,非常にレアなケースであるようにも思えますが,
あなたのプログラムでは事情が異なるのかもしれません.わかりません.

---

で,
とりあえず,そのifの中に実際に処理が来ているのかどうかを調べるところから初めることを勧めます.

「衝突しているハズ」なのにifの中に処理が来ないならば,このifを書くべき場所を間違っているとか,あるいは前記したように「衝突」の判定基準が厳しすぎるのか,とにかく処理が来ない理由を把握して対処してください.

ifの中に処理は来ているのに挙動がおかしいとかいう場合には,dx等の値の遷移を追ってください.
・このifとは別の場所が,このifの処理を台無しにするような値の変更を行っていないか?
・このifの処理が「2回連続で」走ってしまい,結果として「入れ替えて,さらに入れ替えた」という残念なことになっていないか?
等.

アバター
usao
記事: 1887
登録日時: 11年前

Re: c++ 玉の反射について

#5

投稿記事 by usao » 3年前

それはそれとして,もうちょっと「まともな」挙動となる方法に関しては,例えば
「ビリヤード シミュレーション 計算方法」みたいな(いかにもそういう問題を取り扱っていそうな)語で検索してみると良いかもしれません.

calbee
記事: 10
登録日時: 3年前

Re: c++ 玉の反射について

#6

投稿記事 by calbee » 3年前

色々教えて頂きありがとうございます。
本来なら物理計算をすべきですが、調べても良く分かりませんでした…

コード:

  
if(x-x1<=1 || x1-x<=1 && y-y1<=1 || y-y1<=1) {
  a=dx;
  dx=dx1;
  dx1=a;
  b=dy;
  dy=dy1;
  dy1=b;
}
こんな感じで判定範囲を広げたところ、一応跳ね返っているように見えましたが、挙動がおかしいです…1という数字がまずいのでしょうか?
判定範囲が一定でないというか、x軸の範囲が凄く広かったり、教えて頂いたように処理が2回連続で走っているように見られる部分があります…

アバター
usao
記事: 1887
登録日時: 11年前

Re: c++ 玉の反射について

#7

投稿記事 by usao » 3年前

> x-x1<=1 || x1-x<=1 && y-y1<=1 || y-y1<=1

ご自身で書かれた条件を,ご自身で説明できますか?
例えば,

> x-x1<=1

これは,(x <= x1+1)であるときに満たされます.
ざっくり言えば,x1が100のとき,xが101以下であれば常に満たされ(てしまい)ます.
(例えば,一方の座標が100で他方が0のときに「衝突している」とは判定したくないと思いますが,そうであれば,これだといかんのでは?)

---

suggestion:

・「A || B && C」と書いた時,それは「A || (B&&C)」なのか「(A||B) && C」なのか?
 把握していますか?
 慣れないうちは,自分が意図した側になるように明示的に括弧で囲みましょう.
・ 理屈を「日本語で」考えて,そこでまずは「理屈としてまともかどうか」を確認しましょう.
・理屈ができたら,それを素直にコード化しましょう.
 例えば,「xとx1との差が1以内」という条件を考えたならば,素直なコードは「abs(x-x1) <= 1」のようになるでしょう.
・理屈を決める際にはググるのも一つの方法です.
 「玉」が円形や球系なのであれば,それらの衝突判定方法はググれば見つかるかもしれません.
 (円や球同士の判定みたいなのは,きっと誰かがドヤ顔で解説している.)

calbee
記事: 10
登録日時: 3年前

Re: c++ 玉の反射について

#8

投稿記事 by calbee » 3年前

本当だ…条件が足りないですね…

r=半径
((x-x1)^2 + (y-y1)^2 <= (r+r1)^2)
という判定法を見つけたのですが、判定範囲が広くなってしまい、何故かできないです…

教えて頂いた絶対値の方法は、stdlib.hは入れたのですが、接触判定ができていないようで、すり抜けてしまいます…

コード:

if(abs(x-x1) <= 1 && abs(y-y1) <= 1) {
  a=dx;
  dx=dx1;
  dx1=a;
  b=dy;
  dy=dy1;
  dy1=b;
}
で問題ないはずですよね…?

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: c++ 玉の反射について

#9

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

calbee さんが書きました:
3年前
r=半径
((x-x1)^2 + (y-y1)^2 <= (r+r1)^2)
という判定法を見つけたのですが、判定範囲が広くなってしまい、何故かできないです…
そのコードは見せていただけないですか?
ちなみに、C++のプリミティブ型では「^」は累乗ではなくxorの演算子です。
calbee さんが書きました:
3年前
問題ないはずですよね…?
これで問題ないかはわかりません。
・calbeeさんの考えている世界で「1」がどの程度の大きさなのかわからないので、
 当たり判定の範囲が適切かわかりません。
・各識別子の宣言が書かれていないので、型が適切かわかりません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

calbee
記事: 10
登録日時: 3年前

Re: c++ 玉の反射について

#10

投稿記事 by calbee » 3年前

「^」は累乗ではないのですね…知らなかったです。
乗算に直したらできました。教えて頂きありがとうございます(__)
1の方は値が小さすぎたようです。数を増やしたら接触判定が見られました。

アバター
usao
記事: 1887
登録日時: 11年前

Re: c++ 玉の反射について

#11

投稿記事 by usao » 3年前

オフトピック
「玉がどうの」と言われたら宣伝しておかねばなるまい.
(もう6年も前の話かぁ…)
viewtopic.php?f=78&t=14198

返信

“C言語何でも質問掲示板” へ戻る