如何在0.5秒内使用WPF绘制数万个点的线?

22

我正在编写基于WPF的代码,用于展示一个包含大约10,000个点的实时折线图。在我的电脑上,需要大约5秒钟才能显示出一张图片。有没有人有想法如何让它更快,只需在0.5秒内完成呢?

class eee : FrameworkElement
{

    public eee()
    {
        _children = new VisualCollection(this);
        Random rand = new Random();
        DrawingVisual dv = new DrawingVisual();
        using (DrawingContext dx = dv.RenderOpen())
        {
            Pen drawingPen = new Pen(Brushes.Black, 1);
            double x=rand.Next(300);
            double y = rand.Next(300);
            for (double i = 0; i < 1000; i = i + 0.1)
            {
                y = 100 + rand.Next(100);
                dx.DrawLine(drawingPen, new Point(i, x), new Point(i + 1, y));
                x = y;
            }
        }
         _children.Add(dv);
    }

1
Charles的只是点,如果你需要线条,使用相同的方法,它会很好地工作。你必须利用保留的图形系统。 - RandomNickName42
5个回答

38

Charles Petzold做到了这一点。在我的主机上甚至更快(<0.3秒),而且点甚至是数据绑定的! ;)

Tamir Khason也这样做,使用线条,并更深入地探讨了WPF位图样式性能这里

Rico Mariani提供了一些关于高性能3D图形的指导,实质上利用值类型如果经过深思熟虑可以提高吞吐量。

Jianzhong Zhang给出了我最喜欢的有关该主题的教程,通过动画和交互实现三维散点图并包含数万个数据点。


2

我猜这段代码示例主要是为了测试一些不真实的样本或者作为一份作业。

尝试重写OnRender方法并进行以下操作:

Pen drawingPen = new Pen(Brushes.Black, 1);

protected override void OnRender(DrawingContext dc)
{
    dc.DrawRectangle(Background, null, new Rect(RenderSize));


            double x=rand.Next(300);
            double y = rand.Next(300);
            for (double i = 0; i < 1000; i = i + 0.1)
            {
                y = 100 + rand.Next(100);
                dc.DrawLine(drawingPen, new Point(i, x), new Point(i + 1, y));
                x = y;
            }


}

或者对于一些真实数据,考虑根据视觉上下文的分辨率,是否真的需要显示每一个点。(如果你的刻度是0-10,而你生成的点是0.0001、0.00015,它们在你的刻度上真的会有差别吗?)


在我的情况下,由于每次渲染时都会清除内容,因此DrawRectangle可能不是必需的。 - marknuzz

1

这些线应该是可选择的吗?您可以在图像中绘制线条,然后将其作为Image控件的源。这样会更快地绘制图像,但是您将失去与线条交互的能力。


0

你考虑过使用XNA吗?使用显卡可以加速处理。


2
WPF 也使用硬件加速。 - Roman Starkov

0

Monogame是基于XNA的,它仍然活跃。你可以利用它的强大功能来解决一些需要巨大图形性能的特殊任务,甚至将其窗口注入到WPF GUI中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接