| 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 | < Назад | Оглавление | Далее > |