ゲーム開発で見つける最も一般的なスプラインは何ですか?


11

ここでは、ゲーム開発で見られる最も一般的なスプライン、メソッドが曲線を補間するために必要なポイントの数、および曲線ポイントの補間を取得できるデータ型を作成する方法を挙げます。例:ベジェ曲線、Bスプライン、3次スプラインなど。

PS:あらゆる種類のスプライン補間をリストできるように、私はこれをコミュニティーwikiとして置いています。


1
いい質問ですね、IMO。
jacmoe

2
この質問を変更して、特にスプライン補間ではなく補間に適用するように投票します。これは私が質問についてだと思ったものであり、したがって、以下の私の場違いの答えです。
Ricket

あなたの双線形補間は良い答えですが、これらの種類の計算は、たとえば、スプラインフィットや近似などの関連する質問に当てはまると思います。または、多分私は間違っていて、これらもここに行く可能性があります。
chiguire 2010

回答:


4

最も単純なケースは、直線の線形補間です。

(x0、y0)* ------------------------ *(x1、y1)

tが[0、1]の間にあるとします。

function lerp((x0, y0), (x1, y1), t):
    return (x0+(x1-x0)*t, y0+(y1-y0)*t)

3

Catmull-Romスプライン(3次エルミートスプラインの一種)は、カメラパスなどの(追加のコントロールポイントを定義せずに)スムーズなパスを作成する一連のポイントがある場合に非常に便利です。

すべての計算については、以下を参照してください。

http://en.wikipedia.org/wiki/Cubic_Hermite_spline

D3DXを使用している場合、それらを処理するためのいくつかの便利な関数があります(D3DXVec3CatmullRom)


0

編集:申し訳ありませんが、ジェイソンがコメントで指摘しているように、次の答えはスプラインではなく、2次元の線形(または双線形)補間に関するものです。私は誰かがそれが有益であると思うかもしれない場合に備えてそれを削除しないことを選択しています。


単純な3D地形を作成してから、自分のキャラクターがその地形を横切って歩いてほしかった。したがって、地形上の任意のポイントでのキャラクターの高さを見つけるために、バイリニア補間を使用しました。

以下は、バイリニア補間に使用するJavaコードです。

/**
 * Interpolates the value of a point in a two dimensional surface using bilinear spline interpolation.
 * The value is calculated using the position of the point and the values of the 4 surrounding points.
 * Note that the returned value can be more or less than any of the values of the surrounding points. 
 * 
 * @param p A 2x2 array containing the heights of the 4 surrounding points
 * @param x The horizontal position, between 0 and 1
 * @param y The vertical position, between 0 and 1
 * @return the interpolated height
 */
private static float bilinearInterpolate (float[][] p, float x, float y) {
    return p[0][0]*(1.0f-x)*(1.0f-y) + p[1][0]*x*(1.0f-y) + p[0][1]*(1.0f-x)*y + p[1][1]*x*y;
}

/**
 * Finds a 2-dimensional array of the heights of the four points that 
 * surround (x,y).
 *
 * Uses the member variable "verts", an 2D array of Vertex objects which have
 * a member "height" that is the specific vertex's height.
 */
private float[][] nearestFour(float x, float y) {
    int xf = (int) Math.floor(x);
    int yf = (int) Math.floor(y);

    if(xf < 0 || yf < 0 || xf > verts[0].length-2 || yf > verts.length-2) {
        // TODO do something better than just return 0s
        return new float[][]{
                {0.0f, 0.0f},
                {0.0f, 0.0f}
            };
    } else {
        return new float[][]{
                {verts[yf][xf].height, verts[yf][xf+1].height},
                {verts[yf+1][xf].height, verts[yf+1][xf+1].height},
            };
    }
}

バイキュービック補間は、遠方のポイント間でよりスムーズまたはより現実的な補間を提供する可能性があることに注意してください。しかし、最適化を試みて(おそらく時期尚早に)密集したグリッドがあるため、バイリニアを使用することにしました。


質問は、に沿って補間についてですスプライン
ジェイソン・コザック

ごめんなさい; 回答の上部にメッセージが追加されました。
Ricket
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.