0

Is there a more efficient way of drawing lines in WPF other than using

DrawingContext.DrawLine(pen, a, b); ?

Im doing a lot of line drawing in my application, and 99% of the time is spent in a loop making this call.

[a,b] come from a very large list of points which are continually changing. i dont need any input feedback/eventing or anything like that, ... I just need the points drawn very fast.

Any suggestions?

Mark Hall
  • 53,938
  • 9
  • 94
  • 111
wforl
  • 843
  • 10
  • 22

3 Answers3

2

you could try to freeze the Pen. Here is an overview on freezable objects.

Klaus78
  • 11,648
  • 5
  • 32
  • 28
1

This question is really old but I found a way that improved the execution of my code which used DrawingContext.DrawLine aswell.

This was my code to draw a curve one hour ago:

DrawingVisual dv = new DrawingVisual();
DrawingContext dc = dv.RenderOpen();

foreach (SerieVM serieVm in _curve.Series) {
    Pen seriePen = new Pen(serieVm.Stroke, 1.0);
    Point lastDrawnPoint = new Point();
    bool firstPoint = true;
    foreach (CurveValuePointVM pointVm in serieVm.Points.Cast<CurveValuePointVM>()) {
        if (pointVm.XValue < xMin || pointVm.XValue > xMax) continue;

        double x = basePoint.X + (pointVm.XValue - xMin) * xSizePerValue;
        double y = basePoint.Y - (pointVm.Value - yMin) * ySizePerValue;
        Point coord = new Point(x, y);

        if (firstPoint) {
            firstPoint = false;
        } else {
            dc.DrawLine(seriePen, lastDrawnPoint, coord);
        }

        lastDrawnPoint = coord;
    }
}

dc.Close();

Here is the code now:

DrawingVisual dv = new DrawingVisual();
DrawingContext dc = dv.RenderOpen();

foreach (SerieVM serieVm in _curve.Series) {
    StreamGeometry g = new StreamGeometry();
    StreamGeometryContext sgc = g.Open();

    Pen seriePen = new Pen(serieVm.Stroke, 1.0);
    bool firstPoint = true;
    foreach (CurveValuePointVM pointVm in serieVm.Points.Cast<CurveValuePointVM>()) {
        if (pointVm.XValue < xMin || pointVm.XValue > xMax) continue;

        double x = basePoint.X + (pointVm.XValue - xMin) * xSizePerValue;
        double y = basePoint.Y - (pointVm.Value - yMin) * ySizePerValue;
        Point coord = new Point(x, y);

        if (firstPoint) {
            firstPoint = false;
            sgc.BeginFigure(coord, false, false);
        } else {
            sgc.LineTo(coord, true, false);
        }
    }

    sgc.Close();
    dc.DrawGeometry(null, seriePen, g);
}

dc.Close();

The old code would take ~ 140 ms to plot two curves of 3000 points. The new one takes about 5 ms. Using StreamGeometry seems to be much more efficient than DrawingContext.Drawline.

Edit: I'm using the dotnet framework version 3.5

nkoniishvt
  • 2,442
  • 1
  • 14
  • 29
0

It appears that StreamGeometry is the way to go. Even without freezing it, I still get a performance improvement.

wforl
  • 843
  • 10
  • 22