2016-12-07 15 views
0

私はスプラインを持っていましたが、私は可変速度でカーブに沿ってオブジェクトを動かすことができましたが、私は一定の速度で動かしたいと思います。どのように一定の速度でスプラインに沿ってオブジェクトを移動できますか?

public static class SplineCurve { 

public static Vector3 GetPoint (Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t) { 
    t = Mathf.Clamp01(t); 
    float oneMinusT = 1f - t; 
    return 
     oneMinusT * oneMinusT * oneMinusT * p0 + 
     3f * oneMinusT * oneMinusT * t * p1 + 
     3f * oneMinusT * t * t * p2 + 
     t * t * t * p3; 
} 

public static Vector3 GetFirstDerivative (Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t) { 
    t = Mathf.Clamp01(t); 
    float oneMinusT = 1f - t; 
    return 
     3f * oneMinusT * oneMinusT * (p1 - p0) + 
     6f * oneMinusT * t * (p2 - p1) + 
     3f * t * t * (p3 - p2); 
} 

}

私はこの曲線に一定のパラメータtを送信し、ポイントを取得し、そのポイントにオブジェクトを移動するが、これは私に、可変速度を与えています。私は一定のスピードで私のオブジェクトを移動したいどのように私はこれを達成することができますか?


私は特定の距離でtを解くことができる方程式はありますか?

B(t) = (1 - t)^3 * P0 + 3 * (1 - t)^2 * t * P1 + 3 * (1 - t) * t^2* P2 + t^3* P3 

私はこの式を使用している

+0

あなたは微分を計算するように、要因 'でステップ長をスケーリング(希望のスピード)/(微分のノルム) '。 – LutzL

答えて

0

残念なことに、ベジェ曲線の長さは(それが積分楕円形である)閉じ式のように表すことができません。しかし、移動するためには、精度を無視して単純な近似を使用することがあります。

Arbitrary found example - 「私が行ったこと」の一部です。

このアプローチを使用すると、曲線を小さなセグメントに分割し、これらのセグメントの長さを取得し、各セグメントで変化する速度を定義することができます。

+0

あなたは分割する必要もなく、ちょうど十分な間隔で曲線をサンプリングする必要があります各サンプリングされた点の間の線形補間(http://pomax.github.io/bezierinfo/#tracing) –

0

あなたが探しているのは、時間の都度パラメータ化されたベジエ曲線の再パラメータ化です。そのため、「時間点での曲線点t」ではなく、curve point at distance (or ratio) d` "を計算することができます。実際には非常に難しい問題です。そして、あなたが「コンピュータスクリーン」のために働いていることを認識するのが最も効率的です。各ポイントがx/y(/ z)座標を記録するポイントのLUT(ルックアップテーブル) 、時間値、およびあなたは、単純な機能とそのLUTに基づいた曲線に沿って移動できるように、このようにカバーされているカーブ開始からの直線距離:

getCoordinate(d): 
    // get a known coordinate at, or before, distance 'd' 
    s = findBefore(d) 

    // get a known coordinate after distance 'd', 
    // or 'false' if 'd' is actually a real LUT point 
    e = findAfter(d) 

    // if it was a real LUT point, we're done. 
    if (e is false): return LUT[d] 

    // if it wasn't, perform linear interpolation 
    // between the known before/after coordinates, 
    // and treat that as the coordinate-for-distance. 
    return interpolate(d, e, s) 

に沿った距離としてそのLUT [0]が始点、LUT [len/2]が途中の曲線、LUT [len-1]が始点となるように、にLUT を書き込むことで、終わりです。ルジャンドル-guass直交計算のようなものに基づいて、真の数学的な弧の長さ:

心に留めていることを確認してくださいする一つのことは、順序が適切にこれを使用することで、あなたが長さを持つものとして、あなたの曲線をマークする必要があるということです、およびこのLUTの近似距離は、計算した座標間のすべての線形距離の合計に基づいて計算されます。最初に「カーブの長さをユーザーに伝える」汎用目的には最初の文字を使用しますが、実際にカーブに沿って移動するには秒のを使用します。

ではないため、カーブに沿って動くものはです。カーブのポリゴン近似に沿って物を動かしています(99)。時間の99%が正確に何をしたいです)

このコードはfindbeforefindafter関数を指定していないが、これを行うには、あまりにも多くの方法がある - [IV]バイナリサーチ(i = len, v = len >> 1は、LUTをチェックし、より高いです=>i -= vd、より低いd =>i += vは、vがゼロになるまで繰り返し、v >> 1を通じてVを修正し、あなたの境界配列のインデックスを見つけた。

関連する問題