Reputation: 889
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
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
Reputation: 889
It appears that StreamGeometry is the way to go. Even without freezing it, I still get a performance improvement.
Upvotes: 0
Reputation: 11916
you could try to freeze the Pen. Here is an overview on freezable objects.
Upvotes: 2