netlib.narod.ru< Назад | Оглавление | Далее >

Многоугольники и режим заливки

В завершение (по крайней мере этой главы) нам осталось рассмотреть метод FillPolygon. От других закрашиваемых областей многоугольники отличаются тем, что определяющие их линии могут пересекаться и накладываться одна на другую. Это усложняет дело, так как есть два разных способа заливки многоугольников. Существует четыре метода FillPolygon:


Методы FillPolygon класса Graphics



void FillPolygon(Brush brush, Point[] apt)
void FillPolygon(Brush brush, PointF[] apt)
void FillPolygon(Brush brush, Point[] apt, FillMode fm)
void FillPolygon(Brush brush, PointF[] apt, FillMode fm)


Они во всем похожи на метод DrawPolygon, кроме одного необязательного аргумента. FillMode — это перечисление, определяемое в пространстве имен System.Drawing.Drawing2D. У него всего два возможных значения:


Перечисление FillMode



Член Значение Комментарий

Alternate 0 Задано по умолчанию, чередует закрашенные и незакрашенные области фигуры
Winding 1 Закрашивает максимально возможное число внутренних областей фигуры


Режим заливки имеет значение, лишь когда линии, определяющие многоугольник, пересекаются. Он определяет, какие из замкнутых областей будут закрашены, а какие — нет. Если режим заливки в методе FillPolygon не задан, по умолчанию используется FillMode.Alternate. При этом замкнутая область заполняется, только если она отделена от бесконечности нечетным числом границ.

Классический пример — пятиконечная звезда. Ее внутренний пятиугольник закрашивается в режиме Winding, но остается свободным в режиме Alternate.

FillModesClassical.cs

  //---------------------------------------------------
  // FillModesClassical.cs (C) 2001 by Charles Petzold
  //---------------------------------------------------
  using System;
  using System.Drawing;
  using System.Drawing.Drawing2D;
  using System.Windows.Forms;

  class FillModesClassical: PrintableForm
  {
      public new static void Main()
      {
          Application.Run(new FillModesClassical());
      }
      public FillModesClassical()
      {
          Text = "Alternate and Winding Fill Modes (The Classical Example)";
          ClientSize = new Size(2 * ClientSize.Height, ClientSize.Height);
      }
      protected override void DoPage(Graphics grfx, Color clr, int cx, int cy)
      {
          Brush   brush = new SolidBrush(clr);
          Point[] apt   = new Point[5];
          
          for (int i = 0; i < apt.Length; i++)
          {
              double dAngle = (i * 0.8 - 0.5) * Math.PI;
              apt[i] = new Point(
                            (int)(cx *(0.25 + 0.24 * Math.Cos(dAngle))),
                            (int)(cy *(0.50 + 0.48 * Math.Sin(dAngle))));
          }
          grfx.FillPolygon(brush, apt, FillMode.Alternate);

          for (int i = 0; i < apt.Length; i++) 
              apt[i].X += cx / 2;

          grfx.FillPolygon(brush, apt, FillMode.Winding);
      }
  }

Первый цикл for определяет пять концов звезды, выводимой в левой половине клиентской области. Для такого многоугольника устанавливается режим заливки Alternate. Второй цикл for сдвигает вершины звезды в правую часть клиентской области, где многоугольник закрашивается в режиме Winding.


Рис. 5.16.

Обычно в режиме Winding закрашиваются все замкнутые области. Но не всегда все так просто — есть и ряд исключений. Чтобы определить, будет ли закрашена область в режиме Winding, мысленно проведите прямую из любой точки этой области в бесконечность. Если воображаемая линия пересекает нечетное число границ, область закрашивается (так же, как в режиме Alternate). Если же воображаемая линия пересекает четное число границ, то область может быть закрашена, а может остаться и свободной. Такая область закрашивается, если число граничных линий, направленных по часовой стрелке, не равно числу линий, направленных против часовой стрелки.

Немного подумав, можно нарисовать фигуру, внутренняя область которой останется незакрашенной в режиме Winding.

FillModesOddity.cs

  //------------------------------------------------
  // FillModesOddity.cs (C) 2001 by Charles Petzold
  //------------------------------------------------
  using System;
  using System.Drawing;
  using System.Drawing.Drawing2D;
  using System.Windows.Forms;

  class FillModesOddity: PrintableForm
  {
      public new static void Main()
      {
          Application.Run(new FillModesOddity());
      }
      public FillModesOddity()
      {
          Text = "Alternate and Winding Fill Modes (An Oddity)";
          ClientSize = new Size(2 * ClientSize.Height, ClientSize.Height);
      }
      protected override void DoPage(Graphics grfx, Color clr, int cx, int cy)
      {
          Brush    brush = new SolidBrush(clr);
          PointF[] aptf = { new PointF(0.1f, 0.7f), new PointF(0.5f, 0.7f),
                            new PointF(0.5f, 0.1f), new PointF(0.9f, 0.1f),
                            new PointF(0.9f, 0.5f), new PointF(0.3f, 0.5f),
                            new PointF(0.3f, 0.9f), new PointF(0.7f, 0.9f),
                            new PointF(0.7f, 0.3f), new PointF(0.1f, 0.3f)};
          
          for (int i = 0; i < aptf.Length; i++)
          {
              aptf[i].X *= cx / 2;
              aptf[i].Y *= cy;
          }
          grfx.FillPolygon(brush, aptf, FillMode.Alternate);

          for (int i = 0; i < aptf.Length; i++)
              aptf[i].X += cx / 2;

          grfx.FillPolygon(brush, aptf, FillMode.Winding);
      }
  }

Вот результат:


Рис. 5.17.

В следующих главах мы обсудим методы Fill подробнее: FillClosedCurve — в главе 13, a FillRegion и FillPath — в главе 15.


netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz