类Path为一条几何路径,可以通过直线,二次曲线,三次曲线来构成任意路径。Path提供了moveTo, lineTo, curveTo, curveToCubic, closePath方法来构成路径。
下面的例子动态显示一条Bezier曲线。
- /**
- * The animation thread.
- */
- Thread _thread;
- bool _drawn;
- /**
- * The random number generator.
- */
- readonly Random _random = new Random();
- /**
- * The animated path
- */
- readonly Path _path = new Path();
- /**
- * Red brush used to fill the path.
- */
- readonly SolidBrush _brush = new SolidBrush(Color.Red);
- const int Numpts = 6;
- readonly int[] _animpts = new int[Numpts * 2];
- readonly int[] _deltas = new int[Numpts * 2];
- private void Beziers()
- {
- Reset(screenWidth, screenHeight);
- _thread = new Thread(RunBeziers);
- _thread.Start();
- }
- private void RunBeziers()
- {
- Thread me = Thread.CurrentThread;
- if (!_drawn)
- {
- lock (this)
- {
- graphics2D.Clear(Color.White);
- graphics2D.Fill(_brush, _path);
- _drawn = true;
- }
- }
- while (_thread == me)
- {
- DrawDemo(screenWidth, screenHeight);
- }
- }
- /**
- * Generates new points for the path.
- */
- private void Animate(int[] pts, int[] deltas, int i, int limit)
- {
- int newpt = pts[i] + deltas[i];
- if (newpt <= 0)
- {
- newpt = -newpt;
- deltas[i] = (_random.Next() & 0x00000003) + 2;
- }
- else if (newpt >= limit)
- {
- newpt = 2 * limit - newpt;
- deltas[i] = -((_random.Next() & 0x00000003) + 2);
- }
- pts[i] = newpt;
- }
- /**
- * Resets the animation data.
- */
- private void Reset(int w, int h)
- {
- for (int i = 0; i < _animpts.Length; i += 2)
- {
- _animpts[i + 0] = (_random.Next() & 0x00000003) * w / 2;
- _animpts[i + 1] = (_random.Next() & 0x00000003) * h / 2;
- _deltas[i + 0] = (_random.Next() & 0x00000003) * 6 + 4;
- _deltas[i + 1] = (_random.Next() & 0x00000003) * 6 + 4;
- if (_animpts[i + 0] > w / 2)
- {
- _deltas[i + 0] = -_deltas[i + 0];
- }
- if (_animpts[i + 1] > h / 2)
- {
- _deltas[i + 1] = -_deltas[i + 1];
- }
- }
- }
- /**
- * Sets the points of the path and draws and fills the path.
- */
- private void DrawDemo(int w, int h)
- {
- for (int i = 0; i < _animpts.Length; i += 2)
- {
- Animate(_animpts, _deltas, i + 0, w);
- Animate(_animpts, _deltas, i + 1, h);
- }
- //Generates the new pata data.
- _path.Reset();
- int[] ctrlpts = _animpts;
- int len = ctrlpts.Length;
- int prevx = ctrlpts[len - 2];
- int prevy = ctrlpts[len - 1];
- int curx = ctrlpts[0];
- int cury = ctrlpts[1];
- int midx = (curx + prevx) / 2;
- int midy = (cury + prevy) / 2;
- _path.MoveTo(midx, midy);
- for (int i = 2; i <= ctrlpts.Length; i += 2)
- {
- int x1 = (curx + midx) / 2;
- int y1 = (cury + midy) / 2;
- prevx = curx;
- prevy = cury;
- if (i < ctrlpts.Length)
- {
- curx = ctrlpts[i + 0];
- cury = ctrlpts[i + 1];
- }
- else
- {
- curx = ctrlpts[0];
- cury = ctrlpts[1];
- }
- midx = (curx + prevx) / 2;
- midy = (cury + prevy) / 2;
- int x2 = (prevx + midx) / 2;
- int y2 = (prevy + midy) / 2;
- _path.CurveTo(x1, y1, x2, y2, midx, midy);
- }
- _path.ClosePath();
- // clear the clipRect area before production
- graphics2D.Clear(Color.White);
- graphics2D.Fill(_brush, _path);
- RefreshBitmap();
- }
其中实时更新图像需要CompositionTarget.Rendering事件来处理。CompositionTarget.Rendering += CompositionTargetRendering;
- private void CompositionTargetRendering(object sender, EventArgs e)
- {
- bmp.Invalidate();
- }