質問をすることでしか得られない、回答やアドバイスがある。

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

ただいまの
回答率

87.96%

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

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 998
退会済みユーザー

退会済みユーザー

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

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

イメージ説明

//補正量をのを得る
glm::vec2 BoxCollision::getFixValue(glm::vec2 player_min, glm::vec2 player_max, glm::vec2 block_min, glm::vec2 block_max)
{
    //X軸の補正量
    float xA = player_max.x - block_min.x;
    float xB = block_max.x - player_min.x;
    float x;
    float y;

    if (xA < xB)
    {
        x = xA;
    }
    else
    {
        x = xB;
    }

    //Y軸の補正量
    float yA = player_max.y - block_min.y;
    float yB = block_max.y - player_min.y;

    if (yA < yB)
    {
        y = yA;
    }
    else
    {
        y = yB;
    }

    glm::vec2 pos;
    pos.x = x;
    pos.y = y;


    return pos;
}
//交差判定
void BoxCollision::Intersect(BoxCollision& col)
{

//    printf("%f\n",getVector().y);


    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))
    {
        setCol(true);                //当たり判定を設定
        setColTag(col.getMyTag());    //タグを取得
        col.setColTag(getMyTag());    //タグを設定

        glm::ivec2 size = getMax() - getMin();    //サイズ

        glm::vec2 fix = getFixValue(getMin(), getMax(), col.getMin(), col.getMax());    //めりこみ量
        printf("X: %.2f\n", fix.x);
        printf("y: %.2f\n", fix.y);

        if (getVector().x > 0 && getVector().y == 0)
        {
            glm::vec2 p;
            p.x = col.getMin().x - size.x;
            p.y = getMin().y;

            setMinValue(p);
        }else if (getVector().x < 0 && getVector().y == 0)
        {
            glm::vec2 p;
            p.x = col.getMax().x;
            p.y = getMin().y;

            setMinValue(p);

        }
        else if (getVector().y < 0 && getVector().x == 0)
        {
            glm::vec2 p;
            p.y = col.getMax().y;
            p.x = getMin().x;

            setMinValue(p);
        }
        else if (getVector().y > 0 && getVector().x == 0)
        {
            printf("あああ\n");
            glm::vec2 p;
            p.y = col.getMin().y - size.y;
            p.x = getMin().x;

            setMinValue(p);
        }    
        else if (getVector().x > 0 && getVector().y < 0)
        {

//////////////////////////////////////////////////////////////////////////////////////////    
            if ((fix.x < fix.y))
            {

                printf("ああああ\n");
                glm::vec2 p;
                p.x = col.getMin().x - size.x;
                p.y = getMin().y;

                setMinValue(p);

            }
            else {
                printf("うううううう\n");

                glm::vec2 p;
                p.x = getMin().x;
                p.y = col.getMax().y;

                setMinValue(p);

            }
////////////////////////////////////////////////////////////////////////////////////////
        }





    }
    else
    {
        //交差していない        
        setCol(false);
        setColTag(Tag::Invalid);
        col.setColTag(Tag::Invalid);
    }

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • fana

    2021/03/16 17:24 編集

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

    キャンセル

  • fana

    2021/03/16 17:29 編集

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

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2021/03/16 17:43

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

    キャンセル

回答 3

checkベストアンサー

+1

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

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2021/03/15 16:09

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

    キャンセル

  • 2021/03/15 16:29

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

    キャンセル

  • 2021/03/15 16:36

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

    キャンセル

+1

例えば,

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

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

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


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

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

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 15:29

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

    キャンセル

  • 2021/03/15 15:31

    A地点とB地点はX軸のみ違う、Y軸は同じということです。

    キャンセル

  • 2021/03/15 16:00

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

    キャンセル

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

  • ただいまの回答率 87.96%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • トップ
  • C++に関する質問
  • 補正量の少ない方の軸に補正するめり込み量を修正プログラムである現象の修正方法を知りたい。