О чём не пишут в книгах по Delphi
Шрифт:
for I := 0 to 4 do Inc(Star([I].X, 200);
// Устанавливаем режим заливки ALTERNATE. При
// использовании этого режима заполняются горизонтальные
// линии, лежащие между нечетной и четной сторонами
// многоугольника. В результате пятиугольник в центре
// звезды оказывается незаполненным.
SetPolyFillMode(Canvas.Handle, ALTERNATE);
Canvas.Polygon(Star);
Самое интересное здесь то, что обе звезды рисуются
Star
и эта звезда рисуется с режимом заливки WINDING
. При этом закрашиваются все точки, для которых выполняется условие, что луч, выпущенный из этой точки, пересекает контур многоугольника нечетное число раз, т.е. всю внутренность контура. Затем координаты вершин звезды смещаются вправо, и такая же звезда рисуется точно так же, но уже с режимом заливки ALTERNATE
. В этом режиме закрашиваются только те точки, которые оказались между четной и нечетной сторонами многоугольника, и пятиугольник внутри звезды остается незакрашенным. Обратите внимание, что звезду мы здесь рисуем с помощью класса TCanvas
, и только режимы заливки переключаем API-функциями. Следующий шаг — это рисование черной прямоугольной рамки на фоне пересекающихся зеленых линий. Линии рисуются до рамки для того, чтобы показать, что центр рамки действительно остается прозрачным, а не заливается цветом фона. Сама рамка рисуется вызовом одной функции
PolyPolygon
, позволяющей за один раз нарисовать фигуру, ограниченную несколькими замкнутыми многоугольными контурами (листинг 1.36). Листинг 1.36. Рисование рамки с использованием
PolyPolygon
const
Pts: array[0..7] of TPoint = (
(X: 40; Y: 230), (X: 130; Y: 230),
(X: 130; Y: 320), (X: 40; Y: 320),
(X: 60; Y: 250), (X: 60; Y: 300),
(X: 110; Y: 300), (X: 110; Y: 250));
Cnt: array[0..1] of Integer = (4, 4);
...
// Следующая группа команд рисует прямоугольную рамку
Canvas.Pen.Color := clLime;
Canvas.Pen.Width := 3;
// Эти линии рисуются для того, чтобы показать, что
// центр рамки остается прозрачным.
Canvas.MoveTo(30, 220);
Canvas.LineTo(140, 330);
Canvas.MoveTo(140, 220);
Canvas.LineTo(30, 330);
Canvas.Pen.Color := clBlack;
Canvas.Brush.Color := clBlack;
// Функция PolyPolygon позволяет нарисовать несколько
// многоугольников одной командой. Второй параметр
// задает координат всех многоугольников, третий
// параметр задает массив, содержащий число вершин
// каждого из многоугольников. В нашем случае массив
// Cnt
имеет значение (4, 4). Это значит, что первые
// четыре элемента массива PCs задают координаты первого
// многоугольника, следующие четыре - второго. Отметим,
// что указатели на массивы приходится передавать не
// очень простым способом: сначала нужно получить
// указатель на массив с помощью оператора @, а потом
// этот указатель разыменовать. Формальные параметры,
// определяющие указатели на массив, при импорте функции
// PolyPolygon в модуле Windows.dcu объявлены как
// нетипизированные параметры-переменные, поэтому
// компилятор не разрешает просто передать Pts и Cnt в
// качестве фактических параметров - он запрещает
// использовать константы там, где требуются переменные.
// Это не совсем корректно, т.к. локальная
// типизированная константа - это на самом деле не
// константа, а глобальная переменная с локальной
// областью видимости. Тем не менее компилятор имеет
// такую особенность, которую приходится учитывать.
// В данном примере функция PolyPolygon используется для
// рисования двух квадратов, один из которых целиком
// лежит внутри другого. При этом содержимое внутреннего
// квадрата остается незаполненным. Обратите внимание,
// что квадраты рисуются в разных направлениях: внешний
// по часовой стрелке, внутренний - против. Если
// установлен режим заполнения ALTERNATE, это никак не
// влияет на результат, но если установить режим WINDING,
// внутренний квадрат не будет закрашен только в том
// случае, если квадраты рисуются в противоположных
// направлениях.
PolyPolygon(Canvas.Handle, (@Pts)^, (@Cnt)^, 2);
Вся хитрость в этом коде — как передать параметры в функцию
PolyPolygon
. Ее второй параметр — это указатель на массив элементов TPoint
, содержащий координаты вершин всех контуров в массиве: сначала все вершины первого контура в нужном порядке, затем — все вершины второго контура и т.д. Третий параметр — это указатель на массив, содержащий число точек в каждом контуре: первый элемент массива содержит число точек в первом контуре, второй — во втором и т.д. Общее число контуров определяется четвёртым, последним параметром функции PolyPolygon
. Число элементов во втором массиве должно быть равно значению четвертого параметра, a число элементов в первом массиве — сумме значений элементов второго массива. За выполнением этих требований должен следить сам программист, если он ошибется, функция может обратиться к памяти, лежащей за пределами массивов, и последствия будут непредсказуемыми.
Поделиться:
Популярные книги
Ваше Сиятельство
1. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Неудержимый. Книга XIV
14. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря
1. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Подаренная чёрному дракону
Любовные романы:
любовно-фантастические романы
7.07
рейтинг книги
Я Гордый часть 2
2. Стальные яйца
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Бальмануг. Невеста
5. Мир Десяти
Фантастика:
юмористическое фэнтези
5.00
рейтинг книги
Пограничная река. (Тетралогия)
Пограничная река
Фантастика:
фэнтези
боевая фантастика
9.13
рейтинг книги
Сонный лекарь 6
6. Сонный лекарь
Фантастика:
альтернативная история
аниме
5.00
рейтинг книги
Тринадцатый
1. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
6.80
рейтинг книги
Ночь со зверем
3. Оборотни-медведи
Любовные романы:
любовно-фантастические романы
5.25
рейтинг книги
Страж. Тетралогия
Страж
Фантастика:
фэнтези
9.11
рейтинг книги
Кодекс Охотника. Книга XIV
14. Кодекс Охотника
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Не грози Дубровскому! Том VIII
8. РОС: Не грози Дубровскому!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон устанавливает правила
6. Закон сильного
Старинная литература:
прочая старинная литература
5.00