【发布时间】:2016-04-04 14:55:45
【问题描述】:
我想使用点列表绘制函数图形。但是当存在这么多点时,它正在放慢速度。所以我认为如果我可以在不擦除当前绘图的情况下进行绘图,我就不需要存储这些点。我知道Invalidate 清除当前绘图。我该怎么做?
我目前正在使用这种方法:
CoordinateSystem cos = new CoordinateSystem();
List<PointF> points = new List<PointF>();
float a = -20;
void Form1_Tick(object sender, EventArgs e)
{
panel1.Invalidate();
}
void panel1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
double x = a;
double y = Root(x, 3);
cos.DrawSystem(e.Graphics);
points.Add(cos.RelativePoint(new PointF((float)x, (float)y)));
for (int i = 1; i < points.Count - 1; i++)
{
e.Graphics.DrawLine(Pens.Red,points[i],points[i+1]);
}
a += 0.05f;
}
更新
正如你所建议的,我使用了位图来重绘。但是结果的质量对我来说并不好。此外,我不知道如何仅在数据更改时调用Invalidate。因为这里,当Invalidate方法被调用时,数据会发生变化。
代码:
CoordinateSystem cos = new CoordinateSystem();
Bitmap bmp;
float a = -20;
void Form1_Tick(object sender, EventArgs e)
{
panel1.Invalidate();
}
void panel1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
double x = a;
double y = Root(x, 3);
PointF rel = cos.RelativePoint(new PointF((float)x, (float)y));
using (Graphics grp = Graphics.FromImage(bmp))
{
grp.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
cos.DrawSystem(grp);
grp.DrawEllipse(Pens.Red, rel.X - 0.5f, rel.Y - 0.5f, 1, 1);
}
e.Graphics.DrawImage(bmp, 0, 0);
a += 0.01f;
}
更新 2: 好的,我稍微更改了代码。只需在Load 事件中绘制一次坐标系,它现在就具有良好的质量。感谢大家的帮助!
【问题讨论】:
-
您似乎从 Timer 滴答声中调用了
Invalidate()?为什么要这么做。当数据发生变化时,只需要调用 Invalidate 触发表单重绘即可。 -
绘制位图,然后在您的绘制事件中执行 DrawImage。您的计时器事件似乎没有必要。如何更新正在使用的图形变量?
-
是的,绘制到缓冲区图像,然后绘制到您的控件。并且不要将 invalidate 放在 tick 事件处理程序中。
-
只更新tick事件中的变量和位图。绘制事件不应该更新变量,它应该只绘制。看起来你每次都在自己上面绘制坐标系——只画一次。
-
Graphics对象不包含任何图形;它是一个工具,可让您绘制到相关位图上,包括控件的表面。
标签: c# winforms paint coordinate-systems