立方Hermite Spline表现得很奇怪

我正在尝试使用Cubic Hermite Splines绘制图形。 我从这个插值方法页面中抓取了这样做的简单代码。

这是我的代码:

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到0,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

这是结果:

Hermite图

问题是,在图表的某些区域,线条向下 。 查看数据,它永远不会减少。 我不知道算法是否应该这样做,但是对于我正在研究的内容,我希望线条永远不会向下(如果我手工绘制图形,我绝不会让它们向下指向) 。

所以,

  • 图表有问题吗?
  • 该算法应该这样做吗? 如果是这样,有没有这样的事情发生?
  • 我尝试过余弦插值,但不喜欢它的结果。

这是实际的图形function:

 public void DrawGraph(IList 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) = 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插值,没有条件通过一系列递增值的插值曲线也必须在任何地方增加,因此有时您会得到您在此处显示的效果。

有一种称为单调立方插值的东西可以满足您的需求:如果数据点增加,插值曲线也会随处可见。