WPFのお勉強 描画編その3
前回の続きで今回は幾何学的な描画について行う。
前々回でLineオブジェクトを紹介したが、Lineオブジェクトを更新する方法は、オブジェクトの数が増えると、GCの発生が大量に出るようで、1000個とか発行すると、描画処理が重くて話にならなくなる。オブジェクト数が少ないうちは良いが、多くなるにつれ加速度的に重くなるので、不安定で使いにくい。
次はCanvas.Childrenを一度全て消して書き直す方法を考えてみる。この場合、処理にかかる負荷は一定で安定はしているが、全体的に重く大量の折れ線を捌くのにむいているとはいえない。
では、大量の折れ線を捌く方法はないかというとある。StreamGeometryというクラスがありLineクラスでで1つ1つに発生するオーバーヘッドを1箇所にまとめることで負荷を非常に小さくできる。
// Pathの作成 Path MyPath = new Path(); MyPath.Stroke = Brushes.Red; MyPath.StrokeThickness = 1; // StreamGeometryの作成 StreamGeometry geo = new StreamGeometry(); geo.FillRule = FillRule.EvenOdd; using (StreamGeometryContext ctx = geo.Open()) { // 線分の開始と終りは繋がらない ctx.BeginFigure(new Point(0 * (canvas1.Width / _Cycle), _buff.GetValue(0)), false, false); for (int i = 1; i < _Cycle -1; i++) { // 線分の中間は繋がっている ctx.LineTo(new Point(i * (canvas1.Width / _Cycle), _buff.GetValue(i)), true, true); } ctx.LineTo(new Point((_Cycle - 1) * (canvas1.Width / _Cycle), _buff.GetValue((_Cycle - 1))), false, false); } // StreamGeometryの確定 geo.Freeze(); // Pathに登録 MyPath.Data = geo; // Pathをキャンバスに登録 canvas1.Children.Add(geo);
こんな感じで書くと、大量の角がある折れ線でも小さなコストで書くことができる。