在游戏开发中最常见的样条曲线是什么?


11

在此列出在游戏开发中发现的最常见的样条曲线,该方法需要对曲线进行插值的点数以及如何构建允许对曲线点进行插值的数据类型。示例:贝塞尔曲线,B样条曲线,三次样条曲线等。

PS:我将其作为社区Wiki,以便我们可以列出各种样条插值。


1
IMO,这是一个好问题。
jacmoe 2010年

2
我投票赞成将此问题更改为适用于插值,而不是专门用于样条插值。这就是我所想的问题所在,因此下面是我的不当答案。
Ricket 2010年

尽管您的双线性插值法是一个很好的答案,但我认为这类计算可能会涉及一个相关的问题,例如样条曲线拟合或逼近。也许我错了,这些也可以去这里。
chiguire

Answers:


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样条线(一种立方Hermite样条线)可能非常有用。

有关所有数学,请参见:

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

如果您使用的是D3DX,则有一些方便的函数可以处理它们(D3DXVec3CatmullRom)


0

编辑:很抱歉,正如Jason在评论中指出的那样,以下答案与样条线无关,而与二维线性(或双线性)插值有关。我选择不删除它,以防有人发现它提供信息。


我创建了一个简单的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},
            };
    }
}

请注意,三次三次插值可能会在较远的点上呈现更平滑或更逼真的插值;但我选择使用双线性,因为我有一个密集的网格,试图进行优化(也许过早)。


问题是关于样条曲线的
Jason Kozak,2010年

抱歉; 消息已添加到答案的顶部。
Ricket
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.