前もってお詫び申し上げます: 私は正しい Android の種類を知りません。プロパティ「x」と「y」を持つベクター型があると仮定しています。
壁が水平で、現在の速度が「ベクトル」の場合、次のように簡単になります。
vector.y = -vector.y;
x コンポーネントはそのままにしておきます。したがって、類似したことを行う必要がありますが、より一般的です。
これを行うには、y 軸 (水平方向に垂直) のハードコーディングを法線 (ラインに垂直なベクトル) の考え方に置き換えます。
法線は線と直交しているため、線を 90 度回転させることで求めることができます。2d では、ベクトル (a, b) を (-b, a) に変換することで 90 度回転させることができます。したがって、(x1, y1) から (x2, y2) への線がある場合、次の方法で法線を取得できます。
vectorAlongLine.x = x2 - x1;
vectorAlongLine.y = y2 - y1;
normal.x = -vectorAlongLine.y;
normal.y = vectorAlongLine.x;
実際には、元の線の長さは気にしません (また、後で必要に応じて計算に影響します)。そのため、現在の長さに関係なく、法線の長さを 1 にする必要があります。それを現在の長さで割ることでそれを行うことができます。だから、例えば
lengthOfNormal = Math.sqrt(normal.x*normal.x + normal.y*normal.y);
normal.x /= lengthOfNormal;
normal.y /= lengthOfNormal;
そこにあるピタゴラスの定理を使用して長さを取得します。
水平線の場合、y 軸の反転は (i) y 軸に沿ったベクトルの範囲を計算することと同じです。(ii) その量を 2 回減算します。1 回目はその方向の速度を 0 にし、元のバージョンの負のバージョンにします。つまり、次と同じです。
distanceAlongNormal = vector.y;
vector.y -= 2.0 * distanceAlongNormal;
内積は、ベクトルが法線に沿ってどれだけ伸びるかという一般的なケースで使用されます。したがって、水平線に対して vector.y を取得するのと同じことを行います。これは、あなたがおそらく少し信仰を飛躍させなければならないところです. これは内積の性質であり、直角三角形を調べることで自分を納得させることができます。しかし、今のところ、水平線があれば法線 (0, 1) になります。内積は次のようになります。
vector.x * normal.x + vector.y * normal.y
次のように計算します。
distanceAlongNormal = vector.x * 0.0 + vector.y * 1.0;
これは明らかに y コンポーネントを取ることと同じです。
法線に沿って距離を計算したら、実際には、法線に 2 を掛けた値を減算します。ここでの唯一の追加ステップは、法線を乗算して、減算する 2 次元の量を取得することです。それは、通常の順序で減算しようとしているからです。したがって、以前に計算された法線に基づく完全なコードは次のとおりです。
distanceAlongNormal = vector.x * normal.x + vector.y * normal.y;
vector.x -= 2.0 * distanceAlongNormal * normal.x;
vector.y -= 2.0 * distanceAlongNormal * normal.y;
長さ 1 の法線を作成していない場合は、内積によって distanceAlongNormal 値がその量だけスケーリングされるため、ここで長さで割る必要があります。