🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

Q&A

解決済

3回答

1291閲覧

補正量の少ない方の軸に補正するめり込み量を修正プログラムである現象の修正方法を知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

DXライブラリ

DXライブラリとは、DirectXを使ったWindowsソフトの開発に必ず付いて回るDirectXやWindows関連のプログラムを使い易くまとめた形で利用できるようにしたC++言語用のゲームライブラリです。

0グッド

0クリップ

投稿2021/03/14 06:50

編集2021/03/16 08:18

提示画像ですが上右に移動するしながら壁にぶつかるとめり込み量の少ない方の軸へめり込み量を修正するコードです。
提示コードの///の部でめりこみ量の少ない方をif文で分岐して修正するのですが提示画像のように一番上まで行くと提示画像のように下に修正されてしまいます。このバグはどうやって修正すればいいのでしょうか?

考えた事
bool型変数になんかのときといった条件を考えて保存する。
ベクトルを使って交点の座標に修正する。(別の案)

イメージ説明

cpp

1 2//補正量をのを得る 3glm::vec2 BoxCollision::getFixValue(glm::vec2 player_min, glm::vec2 player_max, glm::vec2 block_min, glm::vec2 block_max) 4{ 5 //X軸の補正量 6 float xA = player_max.x - block_min.x; 7 float xB = block_max.x - player_min.x; 8 float x; 9 float y; 10 11 if (xA < xB) 12 { 13 x = xA; 14 } 15 else 16 { 17 x = xB; 18 } 19 20 //Y軸の補正量 21 float yA = player_max.y - block_min.y; 22 float yB = block_max.y - player_min.y; 23 24 if (yA < yB) 25 { 26 y = yA; 27 } 28 else 29 { 30 y = yB; 31 } 32 33 glm::vec2 pos; 34 pos.x = x; 35 pos.y = y; 36 37 38 return pos; 39} 40//交差判定 41void BoxCollision::Intersect(BoxCollision& col) 42{ 43 44// printf("%f\n",getVector().y); 45 46 47 if ((col.getMax().x > box.mMin->x && box.mMax->x > col.getMin().x) 48 && (col.getMax().y > box.mMin->y && box.mMax->y > col.getMin().y)) 49 { 50 setCol(true); //当たり判定を設定 51 setColTag(col.getMyTag()); //タグを取得 52 col.setColTag(getMyTag()); //タグを設定 53 54 glm::ivec2 size = getMax() - getMin(); //サイズ 55 56 glm::vec2 fix = getFixValue(getMin(), getMax(), col.getMin(), col.getMax()); //めりこみ量 57 printf("X: %.2f\n", fix.x); 58 printf("y: %.2f\n", fix.y); 59 60 if (getVector().x > 0 && getVector().y == 0) 61 { 62 glm::vec2 p; 63 p.x = col.getMin().x - size.x; 64 p.y = getMin().y; 65 66 setMinValue(p); 67 }else if (getVector().x < 0 && getVector().y == 0) 68 { 69 glm::vec2 p; 70 p.x = col.getMax().x; 71 p.y = getMin().y; 72 73 setMinValue(p); 74 75 } 76 else if (getVector().y < 0 && getVector().x == 0) 77 { 78 glm::vec2 p; 79 p.y = col.getMax().y; 80 p.x = getMin().x; 81 82 setMinValue(p); 83 } 84 else if (getVector().y > 0 && getVector().x == 0) 85 { 86 printf("あああ\n"); 87 glm::vec2 p; 88 p.y = col.getMin().y - size.y; 89 p.x = getMin().x; 90 91 setMinValue(p); 92 } 93 else if (getVector().x > 0 && getVector().y < 0) 94 { 95 96////////////////////////////////////////////////////////////////////////////////////////// 97 if ((fix.x < fix.y)) 98 { 99 100 printf("ああああ\n"); 101 glm::vec2 p; 102 p.x = col.getMin().x - size.x; 103 p.y = getMin().y; 104 105 setMinValue(p); 106 107 } 108 else { 109 printf("うううううう\n"); 110 111 glm::vec2 p; 112 p.x = getMin().x; 113 p.y = col.getMax().y; 114 115 setMinValue(p); 116 117 } 118//////////////////////////////////////////////////////////////////////////////////////// 119 } 120 121 122 123 124 125 } 126 else 127 { 128 //交差していない 129 setCol(false); 130 setColTag(Tag::Invalid); 131 col.setColTag(Tag::Invalid); 132 } 133 134} 135

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/03/15 06:25

文章を修正しました。
退会済みユーザー

退会済みユーザー

2021/03/16 08:18

文章とタイトルを修正しました。
fana

2021/03/16 08:34 編集

その「補正量が少ない方がどうの」とかいう話の出所らしき場所で議論した方がよくないですかね? https://ja.stackoverflow.com/questions/74674 マルチポスト先で出た案を輸入されても困る.
fana

2021/03/16 08:32 編集

というか,元々の内容と全く異なる形に質問内容を変更するのはやめましょう. 話が丸ごと変更されたため, 既存の回答群とそれらに付随するコメント群は完全に何の話をしているのか不明なものと化しました.
退会済みユーザー

退会済みユーザー

2021/03/16 08:43

すいませんでした。新たに質問を作成するのも良くないと思いました
guest

回答3

0

ベストアンサー

斜めに移動する話に関して年単位で苦労していて,且つ,現状が

どちらか片方の方向のみの場合は正常に判定出来ます。

とのことなのであれば,
もういっそのこと,衝突時刻ら辺での(微小な)移動を縦方向と横方向に分けて2回の移動だということにして扱ったらどうですかね.

二分法か何かで衝突時刻を適当な微小時間の間に囲い込んで
t1 < 衝突時刻 < t2
だということが分かった段階で,
Δt = t2-t1 だけの微小時間での移動量については,「縦に移動→横に移動」(あるいは逆順)と近似して扱ってやれば.

投稿2021/03/15 06:29

fana

総合スコア11985

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/03/15 06:33

具体的にはどうすればいいのでしょうか?線分と線分の交差判定なのでしょうか?どうすればいいのでしょうか?
fana

2021/03/15 07:03

こまったなー. > 線分と線分の交差判定 とかいうのを新たに導入せずとも 現在行えている処理だけを用いてやれる近似手法の案を示しているつもりなのだけど.
退会済みユーザー

退会済みユーザー

2021/03/15 07:05

なんパターンくらいやり方があるのでしょうか?
fana

2021/03/15 07:07

何についてですか?
退会済みユーザー

退会済みユーザー

2021/03/15 07:09

めり込み量を修正方法です。
fana

2021/03/15 07:29

そんなこと言われてもなぁ… 「コレ,方法はNパターンしかないんですよね」みたいに言える話とも思えないし. こまったなー.
退会済みユーザー

退会済みユーザー

2021/03/15 07:36

紙に書いてちゃんと真面目に考えて居るのですが...X軸を先に動かして当たり判定、Y軸を先に動かして当たり判定これで出来るのでしょうか?
guest

0

if ((col.getMax().x > box.mMin->x && box.mMax->x > col.getMin().x) && (col.getMax().y > box.mMin->y && box.mMax->y > col.getMin().y))

この計算式は間違えではありません。しかし、この式はあくまで当たっているか否かという判定だけになります。その為補正をしたい場合はさらにプログラムの修正が必要となります。

AABBの場合は(名称はそのままcolとbox)colの上底とbox下底、colの下底とbox上底、colの右辺とbox左辺、colの左辺とbox右辺と4つに分けて考えた方がよいかと思われます。
その辺のお話はマップチップの当たり判定と同じ考えなので、応用してみて下さい。

投稿2021/03/15 05:04

stdio

総合スコア3307

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/03/15 05:14

マップチップの当たり判定の応用とありますがどうしてもわかりません。もう少し詳細にお願いできますか?
fana

2021/03/15 05:20

所望の補正結果って何? どうなればいいの? っていう話をまず確定させないかぎり,どうしようもないのでは. それと異なる補正結果を生じる話を示されても困るだろうし.
退会済みユーザー

退会済みユーザー

2021/03/15 05:24

斜め左下から右上に向かって当たりブロックの下側と当たるとYだけ修正されて 真横から当たるとXだけ修正する処理が書きたい
fana

2021/03/15 05:29

じゃあ少なくとも 相手の「どこに」 当たったかの判断が要るように思えますね. 物体が > 左下から右上に向かって 移動するとき,単純に考えても,相手矩形の左辺に当たる場合と下辺に当たる場合とがあり得るでしょうから. (加えて,ちょうど角に当たるという場合も考えるのかもしれないし)
stdio

2021/03/15 05:31

詳しくは自力で検索してください。 一応さっくりとした説明だけしておくと、マップチップの当たり判定は点と有限線(軸直線)の当たり判定です。上下左右それぞれで考えた方が頭がごちゃこちゃせずに楽にできると思います。
stdio

2021/03/15 05:34

> 移動するとき,単純に考えても,相手矩形の左辺に当たる場合と下辺に当たる場合とがあり得るでしょうから. 少なくとも相手矩形の左辺に当たる場合は自分の右辺が当たっているという考えに基づいたものです。 この場合、角に関しては上手く調整してくださいとしか言えません。
退会済みユーザー

退会済みユーザー

2021/03/15 06:06 編集

アルゴリズムがわからないのですが?線分と線分の当たり判定でしょうか?
stdio

2021/03/15 06:06

(うわ、すっかり忘れてました) 原理そのものはマリオ君と同じですね。今回はキャラが描かれていないだけで...
退会済みユーザー

退会済みユーザー

2021/03/15 06:22

線分と線分の交差判定を使うのでしょうか?
stdio

2021/03/15 06:27

正確には軸固定の線分ですね。「A地点とB地点はX軸のみ違う」ということです。 その理論なら相手の「どこに」 当たったかの判断が出来るようになると思いますね。
退会済みユーザー

退会済みユーザー

2021/03/15 06:29

軸固定の線分とはどういう意味でしょうか?
stdio

2021/03/15 06:31

A地点とB地点はX軸のみ違う、Y軸は同じということです。
退会済みユーザー

退会済みユーザー

2021/03/15 07:00

X軸、y軸それぞれで判定するということでしょうか?
guest

0

例えば,

pos.y = col.getMin().y - size.y;

には,「補正」される側の補正前の座標だとか移動速度だとかいう要素が一切含まれていないように見受けます.
col.getMin().ysize.y が一定の値である(意味的に定数と呼んでよい)場合,この結果もまた一定の値です.
どっち側からどのあたりにどう当たったとしても常に同じ座標に「補正」されるということです.

これがあなたの意図した処理なのでしょうか?


どうすればいいのでしょうか?

まず,物事をまともに考えることから始めるべきに思えます

  1. 「補正」の結果とはどうなるべきなのか? を定める
  2. 上記1.を達成するための演算内容を考える.
  3. 上記2.で考えた演算内容が妥当か否か(すなわち,1.の結果を生じるか否か)を,まともに検算する.

以上の事柄を実装作業よりも前に行うことです.
3.を十分に行い**「この内容で確実にいける」となってから,その内容を実装します**.

投稿2021/03/15 04:31

fana

総合スコア11985

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問