2

斜めの壁に当たったボールの反射角の計算に問題があります。このチュートリアルから取り上げたアルゴリズムを使用しています。次のようになります (Actionscript 3 の場合)。p1 は現在の速度ベクトルで、p2 は壁の法線です。

private function getReflect2(p1 : Point, p2 : Point) : Point
{

    var wallvec : Point = getNorm(p2);
    var wallnorm  : Point = p2;

    var t : Number = dotProduct(wallvec, p1);
    var n : Number = dotProduct(wallnorm, p1);
    var vt : Point = new Point(wallvec.x * t, wallvec.y * t);
    var vn : Point = new Point(wallnorm.x * -n, wallnorm.y * -n);

    var vx : Number = dotProduct(new Point(1,0), vn) + dotProduct(new Point(1,0), vt);
    var vy : Number = dotProduct(new Point(0,1), vn) + dotProduct(new Point(0,1), vt);
    return new Point(vx, vy);
}

この関数は新しい速度ベクトルを返します。これは、垂直な壁との衝突では正しく行われますが、斜めの壁では正しく行われません。ボールは両側から壁に当たることがあります (つまり、法線が反対方向に突き出ている可能性があります)。

誰でも私のエラーを見つけることができますか? または、より良いアルゴリズムを提案しますか?

4

5 に答える 5

1

関数が機能するには、ベクトル wallvec と wallnorm の大きさが 1 でなければなりません。関数 getNorm() が wallvec の作業を処理していると思われますが、wallnorm は任意の大きさになるようです。

また、実装は、ページにリンクされているアルゴリズムと完全には一致しません。特に、このページでは P2 を壁自体の方向として使用しています。次に、ベクトルを正規化し (方向を変えずに大きさを 1 に減らします)、それを wallvec にコピーします。Wallnorm は、壁の法線を受け取ります (これは既にマグニチュード 1 です)。

私のC実装は次のようになります。wnx と wny は p2c と p2y と同じ方向ですが、それでも大きさで割る必要があることに注意してください。

void solve (double p1x, double p1y, double p2x, double p2y, double *p3x, double *p3y)
{
double wvx = -p2y / sqrt(p2x*p2x+p2y*p2y);
double wvy = p2x / sqrt(p2x*p2x+p2y*p2y);
double wnx= p2x/ sqrt(p2x*p2x+p2y*p2y);
double wny=  p2y/ sqrt(p2x*p2x+p2y*p2y);

double t = wvx*p1x+wvy*p1y;
double n = wnx*p1x+wny*p1y;

double vtx = wvx*t;
double vty = wvy*t;
double vnx = wnx*-n;
double vny = wny*-n;

*p3x=vnx+vtx;
*p3y=vny+vty;

}
于 2008-12-28T00:37:31.410 に答える
0

これはあなたが尋ねたことに対する完全な答えではありませんが、最後の数行は不必要に複雑です。(1, 0) はx軸を表すため、

dotProduct(new Point(1,0), vn)

vn.x に置き換えることができます。したがって、vn と vt の適切なメンバーを参照するだけで、関数の最後の 3 行をより明確にすることができます。

return new Point(vn.x + vt.x, vn.y + vt.y);

ベクトル加算を表現するより便利な方法があるかどうかを知るには、ActionScript に精通していませんが、ベクトル加算を直接表現する方がよいでしょう。

于 2009-01-03T03:36:54.437 に答える
0

垂直で機能する場合 wallvecは、正しくない可能性があります。wallvec 他の値を印刷しましたか?

編集P1: is(1, 0)P2isのときにすべてのベクトル値を提供できます(0, 1)か?

于 2008-12-27T23:51:31.847 に答える
0

その答えは「(つまり、法線が逆方向に突き出ているかもしれない)」の部分ではないかと思います。法線が壁の「中」を指している場合、反射は期待した方向ではなく、壁を通過します。

于 2008-12-28T00:00:30.547 に答える
0

テストされていませんが、これはあなたの速度を反映しているはずです

private function reflectVectors(p1 : Point, p2 : Point) : Point
{
    // get the normalized normal
    var wallNorm:Point = p2.clone();
    wallNorm.normalize(1);

    // v1 = v - 2 * (v.n).n
    var dot:Number = p1.x * wallNorm.x + p1.y * wallNorm.y;
    var diff:Point = wallNorm.clone();
    diff.normalize(dot * -2);
    return p1.add(diff);
}
于 2009-02-06T22:52:53.737 に答える