三次Hermite样条曲线的行为异常 [英] Cubic Hermite Spline behaving strangely
问题描述
我正在尝试使用三次Hermite样条线绘制图形.我从插值方法页中获取了简单的代码.
I'm attempting to draw a graph using Cubic Hermite Splines. I grabbed the simple code to do so from this interpolation methods page.
这是我的代码:
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均匀分布):
With this data (y-values, from 0-1, x-values are distributed evenly from 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
结果如下:
问题是,在图形的某些区域,线向下向下.查看数据,它永远不会减少.我不知道该算法是否应该执行此操作,但是对于我正在做的事情,我希望这些线永远不会向下(如果我手工绘制图形,无论如何我永远都不会使其指向下方)
The problem is, at some areas of the graph, the line goes downward. Looking at the data, it never decreases. I don't know if the algorithm is supposed to do this, but for what I am working on, I want the lines to never go downward (and if I was drawing the graph by hand, I would never make them point downward anyway).
所以
- 绘图有问题吗?
- 该算法应该执行此操作吗?如果是这样,有没有发生这种情况的地方?
- 我尝试过余弦插值,但不喜欢结果.
这是实际的绘图功能:
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插值,没有条件要求通过一系列递增值的插值曲线也必须在任何地方都增大,因此有时您会获得此处显示的效果.
Interpolation methods impose certain continuity conditions in order to give the appearance of a smooth curve. For Hermite interpolation, there is no condition that the interpolating curve through a sequence of increasing values must also be increasing everywhere, and so sometimes you get the effect you show here.
有一种叫做单调三次插值的东西可以满足您的要求:如果数据点在增加,则插值曲线到处也会增加.
There is something called monotone cubic interpolation which does what you want: if the data points are increasing, the interpolating curve will be increasing everywhere also.
这篇关于三次Hermite样条曲线的行为异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!