wforl
wforl

Reputation: 889

Optimizing WPF DrawingContext.DrawLine

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?

Upvotes: 0

Views: 2238

Answers (3)

nkoniishvt
nkoniishvt

Reputation: 2521

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

Upvotes: 1

wforl
wforl

Reputation: 889

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

Upvotes: 0

Klaus78
Klaus78

Reputation: 11916

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

Upvotes: 2

Related Questions