绘制线图c#,数组

时间:2018-04-07 06:57:00

标签: c# wpf xaml

我在c#(3周)中相当新,而StackOverflow虽然通过搜索找不到任何可以满足我在这个页面中的答案。

如何在c#中绘制x ^ 2函数(显然我只对x ^ 2感兴趣,但我选择的任何函数都不感兴趣)

这应该作为用户应用程序在网格中绘制。在此之前,我需要从用户选择自己的二进制文件中收集一些数据,并假设将这些点传递给数组,以便我能够绘制图形。

我不熟悉的问题。

  1. 如何使用数组(如果可能)绘制内存使用量最少的图形?任何链接,参考学习都会很有用。

    private void Pic1D_Click(object sender, RoutedEventArgs e)
    {
        Line myLine = new Line();
        myLine.Stroke = System.Windows.Media.Brushes.LightSteelBlue;
        myLine.X1 = 20;
        myLine.Y1 = 20;
        for (int i=0; i<=8; i++)
        { 
            myLine.X2 = i+20;
            myLine.Y2 = i*i+20;
            myLine.VerticalAlignment = VerticalAlignment.Center;
            myLine.StrokeThickness = 2;
            FunctionGrid.Children.Add(myLine);
            myLine.X2 = myLine.X1;
            myLine.Y2 = myLine.Y1;
    
        }
    }
    
  2. 我正在研究的另一个问题:是否可以通过在数组中使用二进制输入来绘制上图?主要是x值将以二进制表示,y将以二进制表示。有没有一个函数,我可以用它来做这个?我知道如何在二进制内容中转换它,尽管文件本身是一个原始文件。理想情况下,最后我想使用下面的读入文件在2 D中绘制上面的函数。

    if (NewDialogx.ShowDialog() == System.Windows.Forms.DialogResult.OK)
    {
        xPath.Text = NewDialogx.FileName;
    }
    
    byte[] fileBytes = File.ReadAllBytes(@xPath.Text);
    StringBuilder sb = new StringBuilder();
    
    foreach (byte b in fileBytes)
    {
        count++;
        if (count > 4096)
        {
            sb.Append(Convert.ToString(b, 2).PadLeft(1, '!'));
            // GraphPlot[count-512,0,0] = Convert.ToString(b, 2).PadLeft(8, '0');
        }
    }
    
    File.WriteAllText(@"C:\Users\raiti\Desktop\NEW1", sb.ToString());
    
  3. 以下是我尝试这样做的方法。我收到此异常处理错误:

      

    System.ArgumentException:&#39;指定的Visual已经是另一个Visual的子项或CompositionTarget的根。&#39;

    问题在于我不想将其创建为列表,因为这似乎非常不切实际(尽管请纠正我)如果我需要绘制大约10000多条数据线,并且可能占用一些空间。

    我希望我已经足够具体了:)。

1 个答案:

答案 0 :(得分:0)

我打算将其放在评论中,但有太多的方法,我有一些代码要显示。

在wpf应用程序中,我通常不会担心内存使用情况。这可能是在桌面上运行,即使是现在较弱的终端计算机也可以应对大量的图形。

您至少应该考虑使用图形软件。有一堆免费的可能性。我也不会完全忽略将wpf放在一边并将数据转储到磁盘上,以excel方式绘制图表。

如果这是一种学术练习,只有你使用最少的内存才能获胜,那么我必须尝试这些选项并查看他们使用了多少内存。 最有效的图形处理方式应该是各种绘图选项。你可以在图片中画线。尽管位图具有相当大的内存,但如果您有许多行,则可能会保存,因为位图大小不会上升,而其他方法会占用更多内存。 您可以在每个点之间使用绘制线绘制许多线条。 https://msdn.microsoft.com/en-us/library/system.windows.media.drawingcontext(v=vs.110).aspx https://msdn.microsoft.com/en-us/library/ms606810(v=vs.110).aspx 下面的代码(我刚刚碰巧)在地图上绘制了一组线条,用作地图上的叠加层: GeneralStaff map editor

    public static async Task<BitmapSource> GetGridImageAsync(FrameworkElement fe)
    {
        Matrix m = PresentationSource.FromVisual(fe)
            .CompositionTarget.TransformToDevice;
        double dpiFactor = 1 / m.M11;
        return await Task.Run(() =>
        {

            Pen GreyPen = new Pen(Brushes.Gray, 1 * dpiFactor);
            Pen GreyThickPen = new Pen(Brushes.Gray, 2 * dpiFactor);
            GreyPen.Freeze();
            int ix = 0;
            int iy = 0;
            int Width = 1155;
            int Height = 805;
            BitmapSource image = Visuals.CreateBitmap(
               Width, Height, 96,
                drawingContext =>
                {
                    int count = 0;
                    while (ix <= Width)
                    {
                        if (count % 5 == 0)
                        {
                            drawingContext.DrawLine(
                               GreyThickPen, new Point(ix, 0), new Point(ix, Map.Height - 1));
                        }
                        else
                        {
                            drawingContext.DrawLine(
                                GreyPen, new Point(ix, 0), new Point(ix, Map.Height - 1));
                        }
                        ix += 35;
                        count++;
                    }
                    count = 0;
                    while (iy <= Width)
                    {
                        if (count % 5 == 0)
                        {
                            drawingContext.DrawLine(
                            GreyThickPen, new Point(0, iy), new Point(Map.Width -1, iy));
                        }
                        else
                        {
                            drawingContext.DrawLine(
                            GreyPen, new Point(0, iy), new Point(Map.Width - 1, iy));
                        }
                        iy += 35;
                        count++;
                    }
                });
            return image;
        });
    }
}

fe是传入的窗口,我使用缩放,因此线条清晰。它在我的机器上给出了.8的因子。

对于您的目的,这种低级方法可能并非真正必要,在这种情况下您可以使用折线(如Clemens建议的那样)。 使用wpf呈现大量内容的常用方法是使用itemscontrol并绑定itemssource。然后,将绑定的数据模板化为ui对象(在本例中为折线)。 折线采用点集合作为其Points属性。 如果您的数据被收集然后没有变化,您可以将其绑定在数据模板中,如:

<Polyline Points="{Binding Points}" Stroke="Red" StrokeThickness="2" />

其中points是一个公共属性,表示您对集合中每一行绑定到itemssource的某个对象的pointcollection。

如果您的线条应该是弯曲的,那么这要复杂得多。您可以使用路径进行贝塞尔曲线,但您可能需要根据您的点进行计算。 那时我会再次考虑使用专门构建的图形软件。

2)你的阵列。你可能想把它转换成某个地方的pointcollection。这可能是在转换器或视图模型中。 MVVM(和viewmodel)是wpf开发的事实标准模式。

3)你的错误。 当你尝试在两个地方使用一块ui时,你会得到它。 https://social.technet.microsoft.com/wiki/contents/articles/29964.wpf-tips-only-one-parent.aspx 有时它没有错误,但也没有给你预期的结果。 我想我需要查看更多代码来确定原因。