Tôi đang cố vẽ đồ thị bằng cách sử dụng Cubic Hermite Splines. Tôi lấy mã đơn giản để làm như vậy từ trang interpolation methods này.Splite khối Hermite hành xử lạ
Đây là mã của tôi:
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;
}
Với dữ liệu này (giá trị y, 0-1, x-giá trị được phân bố đều 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
Và đây là kết quả:
Vấn đề là, tại một số khu vực của biểu đồ, đường đi xuống dưới. Nhìn vào dữ liệu, nó không bao giờ giảm. Tôi không biết liệu thuật toán có được thực hiện hay không, nhưng đối với những gì tôi đang làm, tôi muốn các dòng không bao giờ đi xuống (và nếu tôi vẽ đồ thị bằng tay, tôi sẽ không bao giờ làm cho chúng hướng xuống dưới) .
Vì vậy,
- Có điều gì sai với đồ họa?
- Thuật toán có được thực hiện không? Nếu vậy, có một nơi mà điều này không xảy ra?
- Tôi đã thử nội suy cosin, nhưng không thích cách nó được bật ra.
Dưới đây là các chức năng đồ họa thực tế:
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);
}
}
Xin chào Snea, tôi đang cố gắng hiểu cách hoạt động của Cubic Hermite Spline. Bạn có thể cho tôi biết cách bạn gọi phương thức HermiteInterpolate của bạn không? – Doro