のは、私がBezier curveB(u)
を持っているとしましょう、私は一定の速度でu
パラメータをインクリメントする場合、私は曲線に沿っcostant高速移動を取得していない、u
パラメータとポイントの関係理由得られた曲線は線形ではないと評価する。ベジェ次曲線:等加速度で移動
David Eberlyのarticleを読んで実装しました。パラメトリックカーブに沿って一定の速度で移動する方法について説明します。
一定の速度でTパラメータを変化させる、Iは、入力として、時間値t
と時間t
速度値を返す速度関数sigma
をとる関数F(t)
を有する、私は曲線に沿っcostant速度運動を得ることができると仮定それは私が供給時間を用いて算出した曲線パラメータu
を取得することができます
float umin, umax; // The curve parameter interval [umin,umax].
Point Y (float u); // The position Y(u), umin <= u <= umax.
Point DY (float u); // The derivative dY(u)/du, umin <= u <= umax.
float LengthDY (float u) { return Length(DY(u)); }
float ArcLength (float t) { return Integral(umin,u,LengthDY()); }
float L = ArcLength(umax); // The total length of the curve.
float tmin, tmax; // The user-specified time interval [tmin,tmax]
float Sigma (float t); // The user-specified speed at time t.
float GetU (float t) // tmin <= t <= tmax
{
float h = (t - tmin)/n; // step size, `n' is application-specified
float u = umin; // initial condition
t = tmin; // initial condition
for (int i = 1; i <= n; i++)
{
// The divisions here might be a problem if the divisors are
// nearly zero.
float k1 = h*Sigma(t)/LengthDY(u);
float k2 = h*Sigma(t + h/2)/LengthDY(u + k1/2);
float k3 = h*Sigma(t + h/2)/LengthDY(u + k2/2);
float k4 = h*Sigma(t + h)/LengthDY(u + k3);
t += h;
u += (k1 + 2*(k2 + k3) + k4)/6;
}
return u;
}
:B(F(t))
私が使用している製品のコアは、次の関数であります210とシグマ関数。 この関数は、速度シグマがコストがかかるときにうまく機能します。シグマが一様なアクセントを表しているなら、私はそれから間違った値を得ています。
直線ベジェ曲線の例です。ここで、P0とP1は制御点、T0は接線です。カーブの定義された:
[x,y,z]= B(u) =(1–u)3P0 + 3(1–u)2uT0 + 3(1–u)u2T1 + u3P2
のは、私は時間t = 3
でカーブに沿った位置を知りたいとしましょう。 I等速の場合:私は私のベジエスプラインを使用して同じ方程式を解く場合
px = v0 * t = 1 * 3 = 3
:私はanalitically位置を算出することができる
V0 = 1;
V1 = 1;
t0 = 0;
L = 10;
:
float sigma(float t)
{
return 1f;
}
と、次のデータ上記のアルゴリズムはn =5
となります。
px = 3.002595;
数値近似を考えると、値はかなり正確です(私はそれについて多くのテストを行いました。細部は省略していますが、私の曲線の実装はうまくあり、カーブ自体の長さはGaussian Quadratureを使ってかなり正確に計算されています。
今、シグマを等加速度関数として定義しようとすると、結果が悪くなります。 次のデータを考慮してください
V0 = 1;
V1 = 2;
t0 = 0;
L = 10;
Iの粒子は、線形運動方程式を用いて、P1に到達する時間を計算することができる:
t
を有する
L = 0.5 * (V0 + V1) * t1 =>
t1 = 2 * L/(V1 + V0) = 2 * 10/3 = 6.6666666
I加速度を計算することができる:
a = (V1 - V0)/(t1 - t0) = (2 - 1)/6.6666666 = 0.15
私はシグマ関数を定義するためのすべてのデータを持っています:
float sigma (float t)
{
float speed = V0 + a * t;
}
私はanaliticallyこの私が時間t =3
後の粒子の以下の速度を期待解決した場合:
Vx = V0 + a * t = 1 + 0.15 * 3 = 1.45
をその位置は次のようになります。
px = 0.5 * (V0 + Vx) * t = 0.5 * (1 + 1.45) * 3 = 3.675
しかし、私はそれを計算した場合上記のアルゴリズムの結果、位置は次のようになります。
px = 4.358587
これは全く異なるfr私が何を期待しているのか
長いポストに申し訳ありません、誰かがそれを読むのに十分な忍耐を持っているなら、私はうれしいでしょう。
私には何が欠けていますか?誰かが私が間違っていることを教えてくれますか?
EDIT: 私は3Dベジエ曲線を試しています。
public Vector3 Bezier(float t)
{
float a = 1f - t;
float a_2 = a * a;
float a_3 = a_2 *a;
float t_2 = t * t;
Vector3 point = (P0 * a_3) + (3f * a_2 * t * T0) + (3f * a * t_2 * T1) + t_2 * t * P1 ;
return point;
}
及びデリバティブ:このように定義
public Vector3 Derivative(float t)
{
float a = 1f - t;
float a_2 = a * a;
float t_2 = t * t;
float t6 = 6f*t;
Vector3 der = -3f * a_2 * P0 + 3f * a_2 * T0 - t6 * a * T0 - 3f* t_2 * T1 + t6 * a * T1 + 3f * t_2 * P1;
return der;
}
とアルゴリズムは、t = 6.6666 ...のためにあなたに何を与えるのですか?それは値10、すなわちLか、別の値ですか? – lmsteffan