我已经创建了一个简短的示例,如果我下面粘贴的代码对您有用,请告诉我。
我不太习惯MathDotNet库,但XML文档足够详细,因此学习曲线并不陡峭,只是另一个.NET库中的许多其他内容之一。
否则,您仍然可以访问库网站查看其文档,除了我不确定是否涵盖插值的几个示例外,您可能会发现与阅读XML文档得到的相同内容。您还可以检查github并查看您要处理的插值的实现。
当然,如果您坚持按照此处描述的算法进行实现,则也可以尝试从头开始实现:
http://en.wikipedia.org/wiki/Neville%27s_algorithm
无论如何,我假设您想利用MathDotNet库执行Neville多项式插值,并在同一图表区域上显示原始和插值数据。
关于其他信息,可以在这里找到一些(仍然不要期望太多):
关于MS Chart,它就像处理任何其他Winforms控件一样,只需查看文档,如果有什么棘手的问题,请指出哪些是困难的,我会尽力让您清楚明白。
到目前为止,坦率地说,我有点困惑于您不理解的内容,是MS Chart、MathDotNet还是两者都有问题?哪一个是你的问题?
无论如何,没有什么特别复杂的,只需将X和Y点传递给MathDotNet库(只要Xs和Ys的底层实现实现了类似数组T[]的IEnumerable<T>即可)。
然后库会为您完成所有的数学计算,您只需要使用给定的插值引擎的Interpolate(...)方法(您必须理解这里的Interpolation意味着一种插值引擎)。
我假设在你的代码片段中:
XPoints
和
YPoints
都是
IEnumerable<T>
集合(因为你提到它们是数组),其中
T
是
Double
、
Single
或任何适合你的 .NET 数字原语类型。请注意,此处不需要解释,保留 HTML 标签即可。
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using MathNet.Numerics.Random;
namespace HelpSO
{
public static class Program
{
[STAThread]
public static void Main(params String[] arguments)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var mainForm = new MainForm();
Application.Run(mainForm);
}
}
public class MainForm : Form
{
private static Chart InitializeChart()
{
var chart = new Chart()
{
Dock = DockStyle.Fill,
};
const String defaultChartAreaName = @"Default";
const String defaultLegendName = @"Default";
const String defaultTitleName = @"Default";
var chartArea = chart.ChartAreas.Add(defaultChartAreaName);
var labelFont = new Font(@"Tahoma", 8f);
var axisX = chartArea.AxisX;
var axisY = chartArea.AxisY;
axisX.Title = @"X";
axisY.Title = @"Y";
axisX.LabelStyle.Format = axisX.LabelStyle.Format = "F4";
axisX.TitleFont = axisY.TitleFont = labelFont;
axisX.LabelStyle.Font = axisY.LabelStyle.Font = labelFont;
axisX.TitleAlignment = axisY.TitleAlignment = StringAlignment.Far;
axisX.MajorGrid.Enabled = axisY.MajorGrid.Enabled = true;
axisX.MinorGrid.Enabled = axisY.MinorGrid.Enabled = true;
axisX.MinorGrid.LineDashStyle = axisY.MinorGrid.LineDashStyle = ChartDashStyle.Dash;
axisX.MinorGrid.LineColor = axisY.MinorGrid.LineColor = Color.Gainsboro;
var legend = chart.Legends.Add(defaultLegendName);
legend.TitleSeparator = LegendSeparatorStyle.ThickGradientLine;
legend.BorderColor = Color.Black;
legend.Title = "Legend";
var title = chart.Titles.Add(defaultTitleName);
title.Text = @"My Awesome interpolated data";
title.Font = new Font(title.Font.FontFamily, 12f);
MainForm.InitializeChartSeries(chart);
return chart;
}
private static void InitializeChartSeries(Chart chart)
{
const String rawDataSeriesName = @"Raw Data";
const String interpolatedDataSeriesName = @"Interpolated Data";
var rawDataSeries = chart.Series.Add(rawDataSeriesName);
var interpolatedDataSeriesSeries = chart.Series.Add(interpolatedDataSeriesName);
rawDataSeries.ChartType = SeriesChartType.FastLine;
interpolatedDataSeriesSeries.ChartType = SeriesChartType.Spline;
rawDataSeries.BorderWidth = interpolatedDataSeriesSeries.BorderWidth = 2;
var rawDataPoints = DataFactory.GenerateDummySine(10, 1, 0.25);
var interpolatedDataPoints = DataFactory.Interpolate(rawDataPoints, 10);
rawDataSeries.Points.DataBind(rawDataPoints, @"X", @"Y", String.Empty);
interpolatedDataSeriesSeries.Points.DataBind(interpolatedDataPoints, @"X", @"Y", String.Empty);
}
public MainForm()
{
this.StartPosition = FormStartPosition.CenterScreen;
var chart = MainForm.InitializeChart();
this.Controls.Add(chart);
}
}
public static class DataFactory
{
public static IList<Point2D<Double, Double>> GenerateDummySine(UInt16 count, Double amplitude, Double noiseAmplitude)
{
if (count < 2)
{
throw new ArgumentOutOfRangeException(@"count");
}
else
{
var dummySinePoints = new List<Point2D<Double, Double>>();
var random = new Random();
var xStep = 1.0 / count;
for (var x = 0.0; x < 1.0; x += xStep)
{
var y = amplitude * Math.Sin(2f * Math.PI * x) + random.NextDouble() * noiseAmplitude;
var dummySinePoint = new Point2D<Double, Double>(x, y);
dummySinePoints.Add(dummySinePoint);
}
return dummySinePoints;
}
}
public static IList<Point2D<Double, Double>> Interpolate(IList<Point2D<Double, Double>> source, UInt16 countRatio)
{
if (countRatio == 0)
{
throw new ArgumentOutOfRangeException(@"countRatio");
}
else if (source.Count < 2)
{
throw new ArgumentOutOfRangeException(@"source");
}
else
{
var rawDataPointsX = source.Select(item => item.X);
var rawDataPointsY = source.Select(item => item.Y);
var xMin = rawDataPointsX.Min();
var xMax = rawDataPointsX.Max();
var interpolation = MathNet.Numerics.Interpolation.CubicSpline.InterpolateNatural(rawDataPointsX, rawDataPointsY);
var listCopy = source.ToList();
var xStep = (xMax - xMin) / (source.Count * countRatio);
for (var x = xMin; x <= xMax; x += xStep)
{
var y = interpolation.Interpolate(x);
var point2D = new Point2D<Double, Double>(x, y);
listCopy.Add(point2D);
}
return listCopy;
}
}
}
public struct Point2D<TX, TY>
where TX : struct, IComparable, IFormattable, IConvertible, IComparable<TX>, IEquatable<TX>
where TY : struct, IComparable, IFormattable, IConvertible, IComparable<TY>, IEquatable<TY>
{
public static Point2D<TX, TY> Empty = new Point2D<TX, TY>();
public Point2D(TX x, TY y)
{
this._x = x;
this._y = y;
}
private readonly TY _y;
public TY Y
{
get
{
return this._y;
}
}
private readonly TX _x;
public TX X
{
get
{
return this._x;
}
}
}
}
随时可以就此提出更多问题。