我正在尝试使用Cubic Hermite Splines绘制图形。我从interpolation methods页面上获取了简单的代码。

这是我的代码:

private float HermiteInterpolate(float y0, float y1, float y2, float y3, float mu)
{
    var mu2 = mu * mu;

    var a0 = -0.5f * y0 + 1.5f * y1 - 1.5f * y2 + 0.5f * y3;
    var a1 = y0 - 2.5f * y1 + 2f * y2 - 0.5f * y3;
    var a2 = -0.5f * y0 + 0.5f * y2;
    var a3 = y1;

    return (a0 * mu * mu2) + (a1 * mu2) + (a2 * mu) + a3;
}

使用此数据(y值从0-1开始,x值从0-21均匀分布):
0, 0.09448819, 0.1102362, 0.1338583, 0.1811024, 0.2283465 ,0.3543307, 0.4645669, 0.480315, 0.480315, 0.527559, 0.527559, 0.527559, 0.527559, 0.527559, 0.527559, 0.6062992, 0.6377953, 0.6377953, 0.6377953, 0.7480315
结果如下:

问题是,在图形的某些区域,线向下。查看数据,它永远不会减少。我不知道算法是否应该执行此操作,但是对于我正在做的事情,我希望这些线永远不会向下(如果我用手绘制图形,无论如何我永远都不会使其指向下方) 。

所以,
  • 图形有问题吗?
  • 该算法应该这样做吗?如果是这样,那有没有发生这种情况的人?
  • 我尝试过余弦插值,但是不喜欢原来的样子。

  • 这是实际的绘图功能:
    public void DrawGraph(IList<float> items)
    {
        for (var x = 0; x < Width; x++)
        {
            var percentThrough = (float)x / (float)Width;
            var itemIndexRaw = items.Count * percentThrough;
            var itemIndex = (int)Math.Floor(itemIndexRaw);
    
            var item = items[itemIndex];
            var previousItem = (itemIndex - 1) < 0 ? item : items[itemIndex - 1];
            var nextItem = (itemIndex + 1) >= items.Count ? item : items[itemIndex + 1];
            var nextNextItem = (itemIndex + 2) >= items.Count ? nextItem : items[itemIndex + 2];
    
            var itemMu = FractionalPart(itemIndexRaw);
    
            var pointValue = HermiteInterpolate(previousItem, item, nextItem, nextNextItem, itemMu);
    
            WritePixel(x, (int)(pointValue * Height) - 1, (1 - FractionalPart(pointValue)), false);
            WritePixel(x, (int)(pointValue * Height), 1.0f, false);
            WritePixel(x, (int)(pointValue * Height) + 1, FractionalPart(pointValue), false);
        }
    }
    

    最佳答案

    这是正常现象。

    插值方法强加了某些连续性条件,以给出平滑曲线的外观。对于Hermite插值,没有条件通过一系列增加值的插值曲线也必须在所有位置都增加,因此有时您会获得此处显示的效果。

    有一种叫做monotone cubic interpolation的东西可以满足您的需求:如果数据点在增加,则插值曲线也会在所有地方都在增加。

    10-08 18:53