Estoy intentando dibujar un gráfico usando Cubic Hermite Splines. Agarré el código simple para hacerlo desde esta página interpolation methods.cúbico Hermite Spline se comporta de manera extraña
Aquí está mi código:
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;
}
Con estos datos (valores de y, a partir de 0-1, valores x se distribuyen uniformemente desde 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
y aquí está el resultado:
El problema es que, en algunas áreas del gráfico, la línea va hacia abajo. Al mirar los datos, nunca disminuye. No sé si se supone que el algoritmo debe hacer esto, pero para lo que estoy trabajando, quiero que las líneas nunca vayan hacia abajo (y si dibujara el gráfico a mano, nunca haría que apuntaran hacia abajo de todos modos) .
Así,
- ¿Hay algo malo con la gráfica?
- ¿Se supone que el algoritmo debe hacer esto? Si es así, ¿hay alguno donde esto no ocurra?
- He intentado la interpolación de coseno, pero no me gustó cómo resultó.
Aquí es la representación gráfica de funciones reales:
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);
}
}
Hola Snea, estoy tratando de entender cómo funciona Hermetic spline cúbico. ¿Podría decirme cómo llama a su método HermiteInterpolate? – Doro