gpt4 book ai didi

c# - 在WinForms应用程序中绘制数千条线的最快方法是什么

转载 作者:行者123 更新时间:2023-12-01 19:39:18 25 4
gpt4 key购买 nike

我有 WinForms 应用程序。我制作了一个用户控件,它根据大约 10k 行的坐标绘制 map 。实际上,并非所有直线都是直线,但是本地图完全缩小时 - 贝塞尔曲线不再相关,而是被直线取代。

本地图缩放时,我的直线和曲线数量较少,因此绘图速度足够快(低于15毫秒)。但是当它完全缩小时 - 我需要绘制所有线条(因为所有线条都适合视口(viewport))。这速度慢得令人痛苦。在我的速度非常快的机器上,大约需要 1000 毫秒,因此在速度较慢的机器上,这将是一个过大的杀伤力。

有没有一种简单的方法可以加快绘图速度?我使用 Graphics 对象进行绘图,并将 Graphics.Scale 属性设置为适合我的控件的 map 。这会减慢速度吗?我使用 Graphics.TranslateTransform() 来确保整个 map 可见。缩放和平移仅在 OnPaint() 事件处理程序中设置一次。

然后有一个循环绘制大约 10k 行。我只是看到他们在屏幕上画画。

也许 WPF 容器会有所帮助?

嗯,我可能可以简化 map 以合并一些线,但我想知道这是否值得。它会使代码变得非常复杂,会引入更多的计算,使用额外的内存,我不知道最终它是否会更快。

顺便说一句,我测试了在我的机器上处理所有行(通过一些额外的计算从一种结构转换为另一种结构)大约需要 10 毫秒。因此 - 仅绘图就花费了 100 倍的时间。

编辑:现在新问题来了。我已经打开双缓冲:

SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);

这是我困惑的 OnPaint() 处理程序:

protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
if (Splines == null) return;

var pens = new[] {
new Pen(TrackColor),
new Pen(TrackColor),
new Pen(RoadColor),
new Pen(RiverColor),
new Pen(CrossColor)
};

var b = Splines.Bounds;
Graphics g = e.Graphics;

g.PageScale = _CurrentScale;
g.TranslateTransform(-b.Left, -b.Top);
int i = 0;
foreach (var s in Splines) {
g.DrawLine(pens[s.T], s.A, s.D);
if (++i > 100) break;
//if (s.L) g.DrawLine(pens[s.T], s.A, s.D);
//else g.DrawBezier(pens[s.T], s.A, s.B, s.C, s.D);
}

foreach (var p in pens) p.Dispose();
}

相信我的话,如果我只从样式中删除 OptimizedDoubleBuffer ,代码就可以工作。当处理程序正确执行双缓冲时,每个 DrawLine 都会使用正确的参数执行。但图形不显示。调整大小期间的 CPU 使用率接近于零。就像所有 DrawLine 调用都被忽略一样。这里发生了什么?

最佳答案

在我最近看到但找不到的相关帖子中,OP 声称在将其控制切换到使用双缓冲时看到了很大的加速。显然,在屏幕上绘制东西很受欢迎。

您可以尝试的另一件事是在缩小时减少绘制的线条中的点列表。您可以在每次更改缩放比例时只执行一次,而不是每帧都进行抽取。

关于c# - 在WinForms应用程序中绘制数千条线的最快方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27892059/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com