比方說,我有一個Bezier curveB(u)
,如果我增加以恆定的速度我沒有獲得沿着曲線costant高速運動u
參數,因爲u
參數和點之間的關係得到的評估曲線不是線性的。貝塞爾三次曲線:以勻加速度移動
我已閱讀並實施了David Eberly的article。它解釋瞭如何沿着參數曲線以恆定速度移動。
假設我有一個功能F(t)
其作爲輸入,在時間t
返回速度值的時間值t
和速度函數sigma
,我可以得到沿曲線a costant速度運動,以恆定的速率變化噸參數:B(F(t))
我使用的是文章的核心是如下功能:
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;
}
它可以讓我計算出的曲線參數u
使用所提供的時間t
和西格瑪功能。 速度西格馬是costant現在功能正常工作。如果西格瑪代表統一加速度,我會從中得到錯誤的值。
下面是一個直貝塞爾曲線的例子,其中P0和P1是控制點,T0是切線。曲線的定義:
[x,y,z]= B(u) =(1–u)3P0 + 3(1–u)2uT0 + 3(1–u)u2T1 + u3P2
比方說,我想知道在時間t = 3
沿曲線的位置。 如果我的等速:
float sigma(float t)
{
return 1f;
}
和下面的數據:
V0 = 1;
V1 = 1;
t0 = 0;
L = 10;
我可以analitically計算位置:
px = v0 * t = 1 * 3 = 3
如果我解決使用我的貝塞爾樣條相同的方程和上面的算法n =5
我得到:
px = 3.002595;
考慮到數值上的近似值,這個值非常精確(我做了很多測試。我省略了細節,但貝塞爾曲線的實現很好,曲線本身的長度使用Gaussian Quadrature進行精確計算。
現在,如果我嘗試將西格馬定義爲統一的加速功能,我會得到不好的結果。 考慮以下數據:
V0 = 1;
V1 = 2;
t0 = 0;
L = 10;
我可以計算時的粒子將使用線性運動方程到達P1:
L = 0.5 * (V0 + V1) * t1 =>
t1 = 2 * L/(V1 + V0) = 2 * 10/3 = 6.6666666
具有t
我可以計算加速度:
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嗡,我期待。
很抱歉,如果有人有足夠的耐心閱讀它,我會很高興。
你有什麼建議?我錯過了什麼?任何人都可以告訴我我做錯了什麼?
編輯: 我想用3D Bezier曲線。這樣定義的:
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 2013-03-15 22:42:47