I have an dynamic List of Point, new Point can be added at any time. I want to draw lines to connect them using different color. Color is based on the index of those points. Here is the code:
private List<Point> _points;
private static Pen pen1 = new Pen(Color.Red, 10);
private static Pen pen2 = new Pen(Color.Yellow, 10);
private static Pen pen3 = new Pen(Color.Blue, 10);
private static Pen pen4 = new Pen(Color.Green, 10);
private void Init()
{
// use fixed 80 for simpicity
_points = new List<Point>(80);
for (int i = 0; i < 80; i++)
{
_points.Add(new Point(30 + i * 10, 30));
}
}
private void DrawLinesNormal(PaintEventArgs e)
{
for (int i = 0; i < _points.Count-1; i++)
{
if (i < 20)
e.Graphics.DrawLine(pen1, _points[i], _points[i + 1]);
else if (i < 40)
e.Graphics.DrawLine(pen2, _points[i], _points[i + 1]);
else if (i < 60)
e.Graphics.DrawLine(pen3, _points[i], _points[i + 1]);
else
e.Graphics.DrawLine(pen4, _points[i], _points[i + 1]);
}
}
I find this method is not fast enough when I have new points coming in at a high speed. Is there any way to make it faster? I did some research and someone said using GraphicsPath could be faster, but how?
[UPDATE] I collect some possible optimizations:
You won't be able to squeeze much more speed out of that code without losing quality or changing to a faster renderer (GDI, OpenGL, DirectX). But GDI will often be quite a bit faster (maybe 2x), and DirectX/OpenGL can be much faster (maybe 10x), depending on what you're drawing.
The idea of using a Path is that you batch many (in your example, 20) lines into a single method call, rather than calling DrawLine 20 times. This will only benefit you if you can arrange the incoming data into the correct list-of-points format for the drawing routine. Otherwise, you will have to copy the points into the correct data structure and this will waste a lot of the time that you are gaining by batching into a path. In the case of DrawPath, you may have to create a GraphicsPath from an array of points, which may result in no time saved. But if you have to draw the same path more than once, you can cache it, and you may then see a net benefit.
If new points are added to the list, but old ones are not removed (i.e. you are always just adding new lines to the display) then you would be able to use an offscreen bitmap to store the lines rendered so far. That way each time a point is added, you draw one line, rather than drawing all 80 lines every time.
It all depends on exactly what you're trying to do.
Doesn't really help to improve performance, but i would put the pens also into a list and writing all this lines in this way:
int ratio = _points.Count / _pens.Count;
for (int i = 0; i < _points.Count - 1; i++)
{
e.Graphics.DrawLine(_pens[i / ratio], _points[i], _points[i + 1]);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With