C# 实现具有大量点的图形的最有效方法

C# 实现具有大量点的图形的最有效方法,c#,graphics,C#,Graphics,我的处境: 我目前正在从事一个项目,该项目将绘制来自多台工业机器的大量数据。该项目是一个Winforms/C项目。目前,我正在使用“System.Drawing”命名空间提供的图形对象中的DrawLine方法。当引导超过500+点左右的图形时,延迟非常明显,甚至会导致绘制方法超时。明确地说,我对开发自己的绘图程序感兴趣,不想使用另一个先前存在的程序 我的观察: 当浏览互联网时,我可以看到下面这样的图表。我的假设是,尽管在下图中绘制了五到六个点,但在实际数据点之间必须绘制数百个“中间”点(以获得每

我的处境: 我目前正在从事一个项目,该项目将绘制来自多台工业机器的大量数据。该项目是一个Winforms/C项目。目前,我正在使用“System.Drawing”命名空间提供的图形对象中的DrawLine方法。当引导超过500+点左右的图形时,延迟非常明显,甚至会导致绘制方法超时。明确地说,我对开发自己的绘图程序感兴趣,不想使用另一个先前存在的程序

我的观察: 当浏览互联网时,我可以看到下面这样的图表。我的假设是,尽管在下图中绘制了五到六个点,但在实际数据点之间必须绘制数百个“中间”点(以获得每个数据点之间的平滑曲线)。这样的图形在调整大小时非常平滑

我的问题:


我怎样才能获得一些现代(超级用户友好)绘图程序所享受的性能呢?

因此,如果你自己写(为什么?),你真的需要避免使用System.Drawing,因为它非常慢。最好的解决方案使用DirectX来利用计算机中的GPU,让他们做他们最擅长的事情。上一次我看到的绘图只使用了一个CPU内核,速度非常慢,所以如果你有数百万个数据点,它就无法扩展

这就是为什么会有第三方解决方案,因为他们有一个团队已经做到了这一点。如果你只是为了好玩或自我探索而这样做,那很好,但如果这是一个真正的产品的一部分,你将很难建立比其他团队更好的东西。是迄今为止我见过的性能更好的图形之一,但我几乎没有全部尝试过,而且我确信还有其他更好的图形。

最有可能的“酷”图形是使用贝塞尔曲线绘制(填充)的,贝塞尔曲线由少量所谓的控制点定义。像System.Drawing这样的API对于这样的图形原语是优化和高效的,它们只需要很少的函数调用

如果曲线不平滑,可能可以在不丢失细节的情况下丢弃点,但这取决于数据

最后一种方法是编写自己的渲染算法,利用特定数据,通过直接像素访问而不是执行图形调用生成图像。然后,您将图像点显到显示屏上

此选项需要良好的图形渲染知识。

你问题的答案似乎很简单。用GPU编程实现图形!有几个GPU编程库,比如.Net。GPU设计用于解决异步问题,如图形显示。这是因为GPU可以使用其数千个线程同时执行独立任务。由于一次执行的线程数量很大,因此对GPU进行编程并不是一项简单的工作,因此您可能需要重新考虑从头开始实现自己的图形应用程序


有趣的事实:您可以使用GPU编程来提高许多异步问题的性能,而不仅仅是图形问题。

我的观察:

虽然有很多方法可以从系统中挤出每一点性能来显示图形,但我真诚地认为,您无法从这个问题的答案中找到解决方案。但是你可以找到很多线索

绘制简单的图形时会出现性能问题,而“现代应用程序”渲染数千个点时不会出现问题,这是为什么呢?游戏可以以4K分辨率每秒渲染60帧以上,并且不能将一帧虚拟图形渲染到曲面

他们是怎么做到的?嗯,他们欺骗优化

如果您不是绘制每个点,而是仅绘制有意义的点,并按照@yves daoust建议的曲线填充其余点,则可以节省一些绘制时间。这就像MP3是如何压缩音频的,它只是删除了你最可能听不到的部分

如果您像@tigran建议的那样启用
双缓冲
,您的结果将更有效地显示在屏幕上,或者您可以在另一个线程中绘制图形,然后绘制该图形,而不是在每个OnPaint中重新绘制

您可以使用Invalidate(Rect)方法仅更新图的相关部分

您可以使用@yves daoust(再次)建议的直接位操作将图形绘制成位图,这可能会大大提高性能,但您必须实现每一个疯狂的功能

虽然
Graphics
object使用的不是GDI而是GDI+,但它针对许多不太复杂的绘图操作进行了很好的优化,您可以使用其他针对性能优化的图形库,如DirectX和Skia

我的建议: 如果你坚持你应该画所有的东西,那么就买一些关于使用C#的图形的书,花一些时间和他们在一起。如果没有,那就买一些低成本、小尺寸的图表库,然后用它来完成

我的处境:
我在Pascal6.0(DOS时代)中实现了一个简单的划线算法,使用BGI、中断、直接内存访问和IO端口。在略读了一些代码之后,可以说我对BDSM感兴趣。

还有@JSteward这怎么会是重复的??我想问的是如何高效地实现一个绘图程序,而不是使用其他程序。答案指向Microsoft图表控件for WInForms,这不是您想要的吗?还是你要写你自己的图表库?写我自己的。我以为我在“我的处境”一词中说得很清楚,但为了让它更清楚,我对它进行了编辑@JSteward@JMaklen如果您还没有这样做,请继续,以提高渲染性能。对于平滑的曲线,你可能会看到,在你的例子中,你实际上是h