Hermite's cubic alloy behaves strangely

I am trying to draw a graph using Cubic Hermite Splines . I took simple code to do this using interpolation methods .

Here is my code:

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; } 

Using this data (y values ​​from 0 to 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

And here is the result:

Hermite Graph

The problem is that in some parts of the chart the line goes down. Looking at the data, it never decreases. I don’t know if the algorithm should do this, but for what I’m working on, I want the lines to never go down (and if I were to draw a graph manually, I would never make them down).

So,

  • Is there something wrong with the graphics?
  • Is this algorithm supposed to be? If so, where is this not happening?
  • I tried cosine interpolation, but I didn’t like how it happened.

Here is the actual graphic display function:

 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); } } 
+6
source share
1 answer

This is normal.

Interpolation methods impose certain continuity conditions to ensure that a smooth curve appears. For Hermite interpolation, there is no condition that the interpolation curve through a sequence of increasing values ​​also grows everywhere, and therefore sometimes you get the effect that you show here.

There is something called monotonic cubic interpolation that does what you want: if the data points increase, the interpolation curve will also increase everywhere.

+10
source

Source: https://habr.com/ru/post/904051/


All Articles