Чтение онлайн

на главную

Жанры

О чём не пишут в книгах по 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
рейтинг книги
Неудержимый. Книга XIV

Идеальный мир для Лекаря

Сапфир Олег
1. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря

Подаренная чёрному дракону

Лунёва Мария
Любовные романы:
любовно-фантастические романы
7.07
рейтинг книги
Подаренная чёрному дракону

Я Гордый часть 2

Машуков Тимур
2. Стальные яйца
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я Гордый часть 2

Бальмануг. Невеста

Лашина Полина
5. Мир Десяти
Фантастика:
юмористическое фэнтези
5.00
рейтинг книги
Бальмануг. Невеста

Пограничная река. (Тетралогия)

Каменистый Артем
Пограничная река
Фантастика:
фэнтези
боевая фантастика
9.13
рейтинг книги
Пограничная река. (Тетралогия)

Сонный лекарь 6

Голд Джон
6. Сонный лекарь
Фантастика:
альтернативная история
аниме
5.00
рейтинг книги
Сонный лекарь 6

Тринадцатый

NikL
1. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
6.80
рейтинг книги
Тринадцатый

Ночь со зверем

Владимирова Анна
3. Оборотни-медведи
Любовные романы:
любовно-фантастические романы
5.25
рейтинг книги
Ночь со зверем

Страж. Тетралогия

Пехов Алексей Юрьевич
Страж
Фантастика:
фэнтези
9.11
рейтинг книги
Страж. Тетралогия

Кодекс Охотника. Книга XIV

Винокуров Юрий
14. Кодекс Охотника
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XIV

Не грози Дубровскому! Том VIII

Панарин Антон
8. РОС: Не грози Дубровскому!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Не грози Дубровскому! Том VIII

Барон устанавливает правила

Ренгач Евгений
6. Закон сильного
Старинная литература:
прочая старинная литература
5.00
рейтинг книги
Барон устанавливает правила