學習學習文化,提高本身算法
拉格朗日插值法,解釋起來差很少就是,【有不少點,我不知道構造這些點的具體函數,可是我能夠嘗試在每一個點的時讓其餘點的縱座標都爲零,這個點爲縱座標爲1,此時獲得一個點的函數,後續每一個點重複操做,最後相加便可】canvas
先上截圖學習
xaml的具體代碼:主要是對canvas的繪圖綁定this
<Grid > <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="auto"/> </Grid.RowDefinitions> <ItemsControl Background="White" x:Name="T1" ItemsSource="{Binding EP }" PreviewMouseLeftButtonUp="T1_PreviewMouseLeftButtonUp"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <ContentControl Content="{Binding UI}"/> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemContainerStyle> <Style > <Setter Property="Canvas.Top" Value="{Binding Y}"/> <Setter Property="Canvas.Left" Value="{Binding X}"/> </Style> </ItemsControl.ItemContainerStyle> </ItemsControl> <Button Height="40" Grid.Row="1" Click="Button_Click" Content="draw"/> </Grid>
後臺代碼spa
namespace 拉格朗日插值 { public class EPS { private double _x; public double X { get { return _x; } set { _x = value; } } private double _y; public double Y { get { return _y; } set { _y = value; } } private Ellipse ellipse; public Ellipse UI { get { return ellipse; } set { ellipse = value; } } public EPS(Point point,bool b=true) { UI = new Ellipse { Stroke = new SolidColorBrush(Colors.Silver), Fill = new SolidColorBrush(b ? Colors.Red : Colors.Blue), Height = b ? 15 : 5, Width = b ? 15 : 5 }; Y = point.Y; X = point.X; } public EPS() { } } /// <summary> /// MainWindow.xaml 的交互邏輯 /// </summary> public partial class MainWindow : Window { public ObservableCollection<EPS> EP { get; set; } public MainWindow() { InitializeComponent(); EP = new ObservableCollection<EPS>(); DataContext = this; } private void T1_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { if (CanDraw) { EP.Clear(); CanDraw = false; } EP.Add(new EPS(e.GetPosition(T1))); //兩點基畫法 //if (EP.Count > 3) //{ // EP.Clear(); //} //if (EP.Count == 2) //{ // for (double i = EP[0].X; i < EP[1].X; i+=1) // { // EP.Add(new EPS(new Point(i,Towpoint(i)),false)); // } //} } double Towpoint(double x) { var b= (EP[0].Y * ((x - EP[1].X) /( EP[0].X - EP[1].X)) ) + (EP[1].Y * ((x - EP[0].X) /( EP[1].X - EP[0].X))); return b; } double MultiPoint(List<EPS> Points,double x) { var k = (from item in Points let l1 = item.Y * (Points.Where(c => c != item).Select(p => x - p.X).Aggregate((a, b) => a * b)) / (Points.Where(c => c != item).Select(p => item.X - p.X).Aggregate((a, b) => a * b)) select l1).Sum(); return k; } bool CanDraw; private void Button_Click(object sender, RoutedEventArgs e) { var k = new EPS[EP.Count]; EP.CopyTo(k, 0); var items = k.ToList(); for (double i = EP[0].X; i < items.Last().X; i+=5) { EP.Add(new EPS(new Point(i, MultiPoint(items, i)), false)); } CanDraw = true; } } }
主要說說關於多點的linq寫法code
拉格朗日插值法的算法通俗而言也就是blog
點的縱座標值乘與未知點的橫座標減去其餘點的橫座標的乘積併除以這個點的橫座標減去其餘點的橫座標的乘積,最後相加便可ip
因此咱們首先得某個點,緊接着過濾掉自身,並開始計算分子的未知點的x減去其餘點的X座標最後使用累加函數相乘便可,固然還要重複一次求分母,並將未知點的X替換爲這個點的X座標get
最後相加便可