0

2 つの 3D ベクトル間で lerp するにはどうすればよいですか? 私は2次元ベクトルにこの方法を使用します:

public Vector2d lerp(Vector2d other, double speed, double error) {
    if (equals(other) || getDistanceSquared(other) <= error * error)
        return other;
    double dx = other.getX() - this.x, dy = other.getY() - this.y;
    double direction = Math.atan2(dy, dx);
    double x = this.x + (speed * Math.cos(direction));
    double y = this.y + (speed * Math.sin(direction));
    return new Vector2d(x, y);
}

注: これは厳密には「線形補間」ではありません。このメソッドは、私が望む一定のレートで補間します。

これとまったく同じことをしたいのですが、3 番目の次元に z コンポーネントを追加します。これどうやってするの?

4

2 に答える 2

0

(u, v)最も簡単な方法は、2 つのベクトルが平面上にあるように変換することです。次に、上記の方法を適用します。次に、元の座標空間に変換します。

これには、回転行列を作成する必要があります。

  1. 2 つのベクトルの外積をとって相互法線ベクトルを取得します。これを呼び出しますcross_1
  2. thisに沿ってその点を定義します。u
  3. thisとの外積をとって、軸の方向であるcross_1ベクトル を取得します。cross_2v
  4. これら 3 つのベクトルのそれぞれを正規化します。this_normそれらを 、cross_2_normおよび と呼びますcross_1_norm

これら 3 つのベクトルは、3x3 正規直交行列として記述できます (各ベクトルは 3 要素の列ベクトルです)。

R = [ this_norm cross_2_norm cross_1_norm ]

今: 3d ベクトルthisotherこの行列で乗算すると、次の形式のベクトルが得られます。

[  u  ]
[  v  ]
[  0  ]

つまり、3 番目の要素が 0 の 3 次元の列ベクトルです (少なくとも、そうすべきです。上記の 3x3 行列を転置するのを忘れている可能性があります)。

したがって、明らかに 3 番目の要素を破棄して、2 要素の列ベクトルを持つことができます。これらを に格納できますVector2d。したがって、上記の方法を適用して補間を行うことができます。

これにより、平面Vector2d内で補間される が得られます。ゼロの 3 番目の要素をそれに付加し、事前に乗算することで、それを空間(u, v)に変換して戻すことができます(これは正規直交であるため、 の逆です)。(x, y, z)R'R


もちろん、ゼロや (反) 平行ベクトルなどの退化したケースを処理する必要があります。これらの場合、外積の一方または両方がゼロであり、正規化できないことを意味します。代わりに任意の方向を選択するだけです。

于 2016-06-10T19:44:24.463 に答える
0

私があなたのコードを正しく理解していれば、dx と dy のオフセットを計算し、それから角度を計算し、最後に sin/cos のペアを計算します - 基本的に dx,dy ベクトルを正規化しているので、次のように書くことができます:

Vector2d delta = other - this;         // I'm not sure about your API here,
delta.normalize();                     // you may need to fix those lines
double x = this.x + (speed * delta.x);
double y = this.y + (speed * delta.y);

これで、Z コンポーネントを簡単に追加できます。

于 2016-06-15T15:40:55.917 に答える