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.
Обычно в режиме 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); } }
Вот результат:
В следующих главах мы обсудим методы Fill подробнее: FillClosedCurve — в главе 13, a FillRegion и FillPath — в главе 15.
netlib.narod.ru | < Назад | Оглавление | Далее > |