Практика программирования (Бейсик, Си, Паскаль)

Закрашивание и заполнение замкнутых областей


Графическое изображение становится более красочным, когда на экране представлены не только контуры геометрических фигур, но и закрашенные или заштрихованные области. Выполнение такого рода операций осуществляется с помощью процедур заливки (англ, paint, fill). Подобно тому, как при построении линий задается точечный шаблон, управляющий воспроизведением пикселов, для площадных объектов существует точно такая же возможность задания двумерной маски, хранящейся в битовом массиве размером 8x8 (Си, Паскаль) или 8x8xk (QBasic, 1 < k < 8). Такая маска, перемещаясь по горизонтали и вертикали, управляет окраской попадающих под ее биты пикселов. К сожалению, идеи такого управления, заложенные в системе QBasic и BGI-пакете, сильно отличаются.

Более-естественными нам представляются алгоритмы заполнения площадных объектов, реализованные фирмой Borland. Для них характерно задание квадратной маски 8x8, управляющей окраской пикселов изображения, накрываемых этой маской. Если в соответствующем разряде маски находится единица, то расположенный под ним пиксел закрашивается в заранее установленный цвет. Пиксел экрана, попадающий под нулевой бит маски, окрашивается в цвет фона. После обработки очередной площадки изображения маска смещается на 8 пикселов вправо. Когда текущая полоска экрана исчерпана, маска перемещается в начало следующей полоски. Системная или пользовательская маска в сочетании с установленными цветами заливки и фона составляют то, что принято называть шаблоном (англ, pattern) заливки.

Для выбора шаблона заливки в BGI-пакете используются две функции (процедуры) — setfillstyle И setfillpattern: setfillstyle(numpat,col); setfiilpattern(pattern,col);

Параметр numpat задается целым числом из диапазона [0,12] или значением соответствующей мнемонической константы (табл. 8.2). 0н позволяет выбрать один из системных шаблонов (numpat < 12) или установить пользовательский шаблон (numpat = 12), описываемый с помощью функции setfillpattern. Параметр col задает код цвета, в который должны окрашиваться пикселы изображения, попадающие под единичные биты маски.




Таблица 8.2. Шаблоны заливки в BGI-пакете



Номер шаблона

Константа ТС

Константа ТР

Способ заполнения области

0

EMPTY FILL

EmptyFiil

Заливается цветом фона

1

S0LIQ_FILL

SolidFill

Заливается цветом col

2

LINE_FILL

Line Fill

Штриховка горизонтальными линиями

3

LT3LASH FILL

LtSlashFill

Тонкая штриховка под 45°

4 SLASH FILL SlashFill Толстая штриховка под 45°
5 BK£T.ASH "ILL EkSlashFill Толстая штриховка под 135&deg
6 LTBKSLASH_?1LL LtBkSlashFill ; Тонкая штриховка под 135°
7

HATCH_FILL

HatchFill

Двойная штриховка, 0° и 90°

8

XHATCH FILL

XHatchFill

Двойная штриховка, 45° и 135°

9

INTERLEAVE FILL

InterleaveFill

Короткие чередующиеся штрихи

10

WIDE_D0T_FILL

WideDotFill

Редкий точечный растр

11

CL0SE D0T FILL

CloseDotFill

Густой точечный растр

12

USER_FILL

UserFill

По шаблону пользователя

Наиболее простой вариант подбора системного шаблона предлагает следующая программа, которая перебирает их в цикле, останавливаясь после вывода очередного образца.

Программа 8_08.с

/* Системные шаблоны заполнения фигур */

#include <stdio.h>

#include <conio.h>

#include <graphics.h>

main() {

int k,gd=0,gm;

int col=14; //желтый цвет для единичных пикселов шаблона

initgraph(sgd,&gm,"");

for(k=0; k<12;k++)

{

cleardevice();

printf("\n номер шаблона=%3",k);

setfillstyle(k,14);

bar(300,100,400,200);

getch();

} Closegraph(); }

Если при выборе шаблона вы остановились на numpat = 12, то перед построением залитых фигур необходимо определить структуру нестандартного узора. В качестве параметра pattern в функции filipattern может выступать любой 8-байтовый массив:

ТС: char patl[] = {0xCC,0x33,0хСС,0x33,0хСС,0x33, 0хСС, 0x33};

setfillpattern(patl,4);

ТР: const

patl:FillPatternType=($CC,$33,$СС,$33,$СС,$33,$СС, $33);



SetFillPattern(patl,4);

Тип данных FillPatternType, описанный в модуле Graph, представляет собой байтовый массив из 8 элементов — array [1. .8] of byte.

В BGI-пакете предусмотрены пять процедур (функций) для построения заполненных геометрических фигур:

  • bar (xl,y1,x2,y2) — залитый прямоугольник без контура;

  • bar3d(x1,y1,x2,y2,d,t) — трехмерный столбик;

  • fillellipse (x, у, rх, rу) — залитый эллипс или окружность;

  • filipoly (п,ху) — залитый многоугольник;

  • sector (х,у, a1,a2, rх, rу) — залитый эллиптический сектор;

  • pieslice (x,y,al,a2, r) залитый круговой сектор.

    В трехмерном столбике первые четыре параметра определяют положение передней грани. Параметр d задает "глубину" столбика, и иногда его рекомендуют выбирать равным четверти ширины (d = 0.25 * (х2 - x1)). Последний аргумент в Си может принимать нулевое или ненулевое значение, а в Паскале — true или false. Если он отличен от о или равен true, то верхняя грань столбика ("крыша") рисуется. В противном случае столбик воспроизводится без крыши, что дает возможность поставить над ним еще один столбик и не заботиться об удалении невидимых линий. В трехмерном столбике заливается только передняя грань.

    Процедура bar3d, как правило, используется для воспроизведения объемных диаграмм. 0днако в ней можно задать нулевую глубину столбика (d = о) и тогда результат ее работы заменяет выполнение двух последовательных процедур:

    bar111,11,99,99);

    rectangle(10,10,100,100);

    Первая из них отображает залитую внутренность прямоугольника, а вторая — обводит его границу.

    Параметры остальных процедур довольно подробно рассматривались в предыдущих разделах.

    Недавно одному из авторов пришлось разрабатывать программные средства выделения замкнутых областей в цифровых электронных картах. Кроме использования самых простых идей — выделение цветом и штриховками, -наиболее плодотворный результат при выводе на дисплей был достигнут регулярными заполнителями с помощью заливочных шаблонов. Самая богатая коллекция таких шаблонов, которая была известна нам по литературе, насчитывала 28 образцов [13]. 0днако по своему разнообразию этот набор показался нам недостаточно выразительным. Кроме того, в нем отсутствовала какая-либо классификация шаблонов. Пришлось потратить несколько дней на эксперименты с редактором образов в системе Builder C++, после чего на свет появилось более сотни шаблонов. Их мы и представляем нашим читателям в надежде, что наиболее любознательные сумеют построить еще не один десяток приятных узоров.



    Программа 8_09.с

    /* Пользовательские шаблоны заполнения фигур

    #include <stdio.h>

    #include <conio.h>

    #include <graphics.h>

    #define Nmax 111

    main()

    {

    int k,gd=0,gm;

    unsigned char pattern[Nmax][8] ={

    //Массив заливочных шаблонов 8x8

    //==== Сплошная заливка

    //шаблон 0 = очистка цветом фона

    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},

    //шаблон 1 = сплошная заливка установленным цветом

    {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},

    //==== Штриховка сплошными линиями

    //= по горизонтали

    //шаблон 2 = горизонтали (линия — 1 пиксел, зазор — 7)

    {0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00},

    //шаблон 3 = горизонтали (2:6)

    {0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},

    //шаблон 4 = горизонтали (3:5)

    {0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00},

    //шаблон 5 = горизонтали (4:4)

    {0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00, 0x00},

    //шаблон б = горизонтали (5:3)

    {0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00, 0x00},

    //шаблон 7 = горизонтали (6:2)

    {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00},

    //шаблон 8 = горизонтали (7:1)

    {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00},

    //шаблон 9 = горизонтали (1:1)

    {0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00},

    //шаблон 10.= горизонтали (1:3)

    {0xFF,0x00,0x00,0x00,0xFF,0x00,0x00,0x00},

    //шаблон 11 = горизонтали (3:1)

    {0xFF, 0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00},

    //шаблон 12 = горизонтали (2:2)

    {0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00},

    //= по вертикали //шаблон 13 = вертикали (1:7)

    {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80},

    //шаблон 14 = вертикаль (1:3)

    {0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88},

    //шаблон 15 = вертикаль (2:6)

    {0хС0,0хС0, 0хС0,0хС0,0хС0,0хС0,0хС0, 0хС0.},

    //шаблон 16 = вертикаль (3:5)

    {0хЕ0,0хЕ0,0хЕ0,0хЕ0,0хЕ0,0хЕ0,0хЕ0,0хЕ0},

    //шаблон 17 = вертикаль (4:4)

    {0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0},

    //шаблон 18 = вертикали (5:3)

    {0xFS, 0xF8,0xF8,0xF8,0xF8,0xF8,0xF8,0xF8},

    //шаблон 19 = вертикали (6:2)

    {0xFC,0xFC,0xFC,0xFC,0xFC,0xFC, 0xFC, 0xFC},

    //шаблон 20 = вертикали (7:1)

    (0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE},



    //шаблон 21 = вертикали (1:1)

    {0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA},

    //шаблон 22 = вертикали (3:1)

    {0xEE, 0xEE, 0xEE,0xEE,0xEE,0xEE,0xEE,0xEE},

    //шаблон 23 = вертикали (2:2)

    {0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC},

    //==== прямоугольная двойная штриховка

    //шаблон 24 = сетка (1:7,1:7)

    {0xFF,0x80,0x80,0x80,0x80,0x80,0x80,0x80},

    //шаблон 25 = сетка (2:6,2:6)

    {0xFF,0xFF,0хС0,0хС0,0хС0,0хС0,0хС0, 0хС0},

    //шаблон 26 = сетка (3:5,3:5)

    {0xFF,0xFF,0xFF,0хЕ0,0хЕ0,0хЕ0,0хЕ0, 0хЕ0},

    //шаблон 27 = сетка (4:4,4:4)

    {0xFF,0xFF,0xFF,0xFF,0xF0,0xF0,0xF0, 0xF0},

    //шаблон 28 = сетка (5:3,5:3)

    {0xFF,0xFF,0xFF,0xFF,0xFF,0xFS,0xFS,0xF8},

    //шаблон 29 = сетка (6:2,6:2)

    {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFC, 0xFC},

    //шаблон 30 = сетка (7:1,7:1)

    {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE},

    //шаблон 31 = сетка (2:2,2:2)

    {0xFF,0xFF,0x99,0x99,0xFF,0xFF,0x99, 0x99},

    //=== штриховка по диагонали //шаблон 32 = справа налево (1:10)

    {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80},

    //шаблон 33 = справа налево (3:7)

    {0x83,0x07,0х0Е,0xlC,0x38,0x70,0хЕ0, 0хС1},

    //шаблон 34 = справа налево (6:3)

    {0xC7,0x8F,0x1F,0хЗЕ,0х7С,0xF8,0xFl, 0хЕЗ},

    //шаблон 35 = слева направо (1:10)

    {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01},

    //шаблон 36 = слева направо (3:7)

    (0хС1,0хЕ0,0x70,0x38,0xlC,0x0E,0x07,0x83},

    //шаблон 37 = слева направо (6:3)

    {0хЕЗ,0xFl,0xF8,0х7С,0хЗЕ,0xlF,0x8F, 0xC7},

    //==== косоугольная двойная штриховка

    //шаблон 38 = штриховка (1:6,1:6)

    {0x81,0x42,0x24,0x18,0x18,0x24,0x42,0x81},

    //=== Штриховка штриховыми линиями

    //= по горизонтали

    //шаблон 39 = штрихи (4*1:4,4) в шахматном порядке

    {0xF0,0x00,0x00,0x00,0x0F,0x00,0x00,0x00},

    //шаблон 40 = штрихи (5*1:3,4) в шахматном порядке

    {0xF8,0x00,0x00,0x00,0xlF,0x00,0x00,0x00},

    //шаблон 41 = штрихи (4*2:4,4) в шахматном порядке

    {0xF0,0xF0,0x00,0x00,0x0F,0x0F,0x00,0x00},

    //шаблон 42 = штрихи (5*2:3,4) в шахматном порядке

    {0xF8,0xF8,0x00,0x00,0xlF,0xlF,0x00,0x00},

    //шаблон 43 = редкие штрихи (4*1:4,7)



    {0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00},

    //шаблон 44 = сплошная и штриховая линии

    {0xFF,0x00,0x00,0x00,0xF0,0x00,0x00,0x00},

    //= по вертикали //шаблон 45 = редкие штрихи (4*1:4,7)

    {0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00},

    //шаблон 46 = штрихи (4*1:4,4) в шахматном порядке

    {0x80,0x80,0x80,0x80,0x08,0x08,0x08,0x08},

    //==== Волнообразные линии //= по горизонтали

    //шаблон 47 = тонкие с небольшой амплитудой

    {0xF0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00},

    //шаблон 48 = толстые с небольшой амплитудой

    {0xF0,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00},

    //шаблон 49 = тонкие с большой амплитудой

    (0x81,0x42,0x24,0x18,0x00,0x00,0x00,0x00},

    //шаблон 50 = толстые с большой амплитудой

    {0x81,0хСЗ,0x66,0хЗС,0x18,0x00,0x00,0x00},

    //= по диагонали //шаблон 51 = слева направо

    {0x10,0x10,0x10,0xF0,0x01,0x01,0x01, 0x0F},

    //==== Растровые сетки //шаблон 52 = густые точки в шахматном порядке (1:1,1)

    {0x00,0x55,0x00,0хАА,0x00,0x55,0x00,0хАА},

    //шаблон 53 = густые точки в шахматном порядке (1:3,2)

    {0x00,0x44,0x00,0x11,0x00,0x44,0x00,0x11},

    //шаблон 54 = мелкие редкие точки в шахматном порядке

    {0x22,0x00,0x00,0x00,0x88,0x00,0x00,0x00},

    //шаблон 55 = средние точки в шахматном порядке

    {0x00,0хбб,0x66,0x00,0x00,0x99,0x99,0x00},

    //шаблон 56 = средние редкие точки в шахматном порядке

    {0x00,0x00,0x30,0x30,0x00,0x00,0x03,0x03},

    //шаблон 57 = средние очень редкие точки в шахматном порядке

    {0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00},

    //шаблон 58 = крупные точки

    {0x00,0x00,0хЗС,0хЗС,0хЗС,0хЗС,0x00,0x00},

    //шаблон 59 = густая шахматная доска

    {0хСС,0x33,0хСС,0x33,0хСС,0x33,0хСС,0x33},

    //шаблон 60 = очень густая шахматная доска

    {0хАА,0x55,0хАА,0x55,0хАА,0x55,0хАА, 0x55},

    //==== Фигуры в узлах прямоугольной сетки

    //шаблон 61 = крестики

    {0x10,0x10,0х7С,0x10,0x10,0x00,0x00,0x00},

    //шаблон 62 = пунктирные крестики

    (0x10,0x00,0x54,0x00,0x10,0x00,0x00,0x00},

    //шаблон 63 = жирные кресты

    {0x00,0x00,0x18,0хЗС,0хЗС,0x18,0x00,0x00},

    //шаблон 64 = сетка из больших ромбиков



    {0x00,0x18,0хЗС,0х7Е,0х7Е,0хЗС,0x18,0x00},

    //шаблон 65 = сетка из больших квадратов

    {0x00,0х7Е,0х7Е,0х7Е,0х7Е,0х7Е,0х7Е, 0x00},

    //шаблон 66 = залитые квадраты 5x5

    {0xF8,0xF8,0xF8,0xF8,0xF8,0x00, 0x00, 0x00}, //шаблон 67 = залитые квадраты 6x6

    {0xFC,0xFC,0xFC,0xFC,0xFC,0xFC,0x00, 0x00},

    //шаблон 68 = залитые квадраты 7x7

    {0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0x00},

    //шаблон 69 = отдельные большие квадратики

    {0x00,0х7Е,0x42,0x42,0x42,0x42,0х7Е,0x00},

    //шаблон 70 = отдельные маленькие квадраты

    {0x00,0x00,0хЗС,0x24,0x24,0хЗС,0x00,0x00},

    //шаблон 71 - квадратики с точками в центре

    (0x00,0х7Е,0x42,0х5А,0х5А,0x42,0х7Е, 0x00},

    //шаблон 72 = символ "х"

    (0x00,0x42,0x24,0x18,0x18,0x24,0x42, 0x00},

    //шаблон 73 = символ "у"

    {0x00,0x44,0x28,0x10,0x10,0x10,0x00,0x00},

    //шаблон 74 = галочки

    {0x00,0x42,0x24,0x18,0x00,0x00,0x00, 0x00},

    //шаблон 75 = перевернутые галочки

    {0x00,0x00,0x00,0x18,0x24,0x42,0x00,0x00},

    //шаблон 76 = тонкие стрелки вверх

    {0x10,0x38,0x54,0x10,0x10,0x10, 0x00, 0x00}, //шаблон 77 = тонкие стрелки вниз

    {0x10,0x10,0x10,0x54,0x38,0x10,0x00,0x00},

    //шаблон 78 = тонкие стрелки влево

    {0x00,0x20,0x40,0xFC,0x40,0x20,0x00,0x00},

    //шаблон 79 = тонкие стрелки вправо

    {0x00,0x10,0x08,0xFC,0x08,0x10,0x00, 0x00},

    //шаблон 80 = жирные стрелки влево

    (0x00,0x08,0x18,0x3F,0x3F,0x18,0x08,0x00},

    //шаблон 81 = двойные стрелки по вертикали

    {0x20,0x70,0хА8,0x22,0x22,0х8А,0x07,0x02},

    //шаблон 82 = двойные стрелки по горизонтали

    {0x24,0x02,0xlF,0x02,0x24,0x40,0xFS, 0x40},

    //шаблон 83 = контуры ромбиков по сетке

    {0x00,0x10,0x28,0x44,0x28,0x10,0x00,0x00},

    //шаблон 84 = залитые ромбики и точки

    {0x81,0x18,0х3С,0х7Е,0х7Е,0хЗС,0x18,0x81},

    //шаблон 85 = залитые ромбики по вертикали

    {0x18,0хЗС,0хЗС,0х7Е,0х7Е,0хЗС,0хЗС,0x18},

    //шаблон 86 = кружочки на сетке (d=6)

    {0x00,0хЗС,0x42,0x42,0x42,0x42,0хЗС,0x00},

    //шаблон 87 = кружочки на сетке (d=5)

    {0x44,0x38,0x00,0x00,0x00,0x38,0x44,0x44},

    //шаблон 88 = не залитые квадратики



    (0x80,0x7F,0x41,0x41,0x41,0x41,0x41,0x7F},

    //шаблон 89 = точечная сетка с точкам в узлах

    {0x08,0x00,0x08,0x50,0x08,0x00,0x08, 0x00},

    //==== Фигуры в шахматном порядке

    //шаблон 90 = ромбики в шахматном порядке

    {0x00,0x18,0хЗС,0х7Е,0х7Е,0хЗС,0x18,0x00},

    //шаблон 91 = густые мелкие квадратики в шахматном порядке

    {0xF0,0xF0,0xF0,0xF0,0x0F,0x0F,0x0F,0x0F),

    //шаблон 92 = более крупные квадраты в шахматном порядке

    {0хСС,0x33,0хСС,0x33,0хСС,0x33,0хСС,0x33},

    //шаблон 93 = контуры квадратиков в шахматном порядке

    {0x42,0хСЗ,0хЗС,0x24,0x24,0хЗС,0хСЗ,0x42},

    //==== Узоры //шаблон 94 = залитые кирпичики по горизонтали

    {0x00,0xFB,0xFB,0xFB,0x00,0xDF,0xDF,0xDF},

    //шаблон 95 = не залитые кирпичики по горизонтали

    {0x00,0xFB,0x0A,0xFB,0x00,0xDF,0x50,0xDF},

    //шаблон 96 = залитые кирпичики по вертикали

    {0хЕЕ,0хЕЕ,0х0Е,0хЕЕ,0хЕЕ,0хЕ0,0хЕЕ,0хЕЕ},

    //шаблон 97 = не залитые кирпичи по диагонали

    (0x01,0x82,0x44,0x28,0x10,0x20,0x40,0x80},

    //шаблон 98 = не,залитые кирпичи по диагонали

    {0x80,0x41,0x22,0x14,0x08,0x04,0x02,0x01},

    //шаблон 99 = волнистый узор

    {0x94,0x84,0x48,0x30,0x00,0хС1,0x22,0x14},

    //шаблон 100 = спиральный узор

    {0xFF,0x01,0xVD,0x45,0x5D,0x41,0x7F,0x00},

    //шаблон 101 = узор 1

    {0x00,0хЕС,0х2А,0х2А,0х2А,0х2А,0хЕС,0x00},

    //шаблон 102 = узор 2

    {0x00,0x00,0х7Е,0x42,0х7Е,0x42,0х7Е,0x42},

    //шаблон 103 = узор 3

    {0x00,0x50,0хЗЕ,0x6D,0x7F,0x63,0x36,0xF0},

    //шаблон 104 = узор 4

    {0x92,0x24,0x49,0x92,0x24,0x49,0x92,0x24},

    //шаблон 105 = узор 5

    {0хВ1,0x22,0x14,0x14,0x22,0x91,0x48,0x24},

    //шаблон 106 = узор 6

    {0x02,0x91,0x68,0x08,0x10,0x16,0x89,0x40},

    //шаблон 107 = узор 7

    {0хСЗ,0x42,0х5А,0х7Е,0х7Е,0х5А,0x42, 0хСЗ},

    //шаблон 108 = узор 8

    {0x03,0x18,0x60,0x80,0x80,0x40,0x20,0x18},

    //шаблон 109 = узор 9

    {0xBF,0xA0,0xA0,0xBF,0xFB,0x0A,0x0A,0xFB},

    //шаблон 110 = узор 10

    {0xFF,0x81,0xBD,0xA5,0xA5,0xBD,0x81,0xFF},

    //шаблон 111 = узор 11

    {0xFF,0x81,0x81,0x99,0x99,0x81,0x81,0xFF}};

    initgraph(&gd,&gm,""); f0r(k=0;k<Nmax;k++) {



    cleardevice();

    g0t0xy(1,1);

    printf("\n номер шаблона=%d", k) ;

    setfillpattern(&pattern[k] [0],4);

    setfillstyle(12, 14);

    bar3d(240,40,440,240,16,l);

    getch (); } }

    0дной из самых интересных процедур заливки является функция fi00dfiii: fl00dfill(x,у,eg);

    Работает эта процедура с замкнутой областью, внутренней или внешней части которой принадлежит точка с координатами (х,у). Параметр eg задает цвет пикселов, составляющих границу области. Заливке подвергается та часть области, которой принадлежит точка (х,у). При этом предполагается, что в заливаемой области не встречаются пикселы цвета eg. Если в границе области будет обнаружен микроскопический разрыв хотя бы в один пиксел, то узор-заполнитель обязательно просочится через него и заливка распространится как на внутреннюю, так и на внешнюю части области. При заливке цвет границы сохраняется. 0днако в случае совпадения цвета границы с цветом окраски единичных пикселов шаблона получится область без ярко выраженной границы. Повторная перезаливка такой области уже невозможна.

    В системе QBasic мы уже демонстрировали возможность построения залитого прямоугольника с помощью оператора LINE .. . BF. Заполнение его

    внутренности ограничено сплошной окраской пикселов в заданный цвет. Все остальные возможности по построению закрашенных или заштрихованных фигур сосредоточены в операторе PAINT, пользоваться которым не так уж и легко. 0ператор PAINT допускает несколько модификаций:

    PAINT (x,y),[c0l],eg PAINT (x,y),Ml$,cg PAINT (x,y),Ml$,cg,M2$

    Первый формат оператора очень напоминает функцию fi00dfill, заливающую внутреннюю или внешнюю часть области заданным цветом c0l или цветом переднего плана, ранее установленным по оператору C0L0R.

    Второй формат отличается от первого только тем, что цвет и узор заливки задаются с точностью до бита в строке M1$, длина которой может достигать 64 байт. Первые четыре байта строки М1$ определяют цветовые атрибуты восьми смежных пикселов на экране. При этом в первом байте такой четверки сосредоточены биты управления синим цветом, во втором байте — биты управления зеленым цветом, в третьем байте — биты управления красным цветом, а в последнем байте — биты управления повышенной яркостью. Четыре следующих байта строки MI$ определяют аналогичные атрибуты восьми смежных пикселов следующей строки и т. д. В полном объеме строка-шаблон позволяет задать цветовые атрибуты пикселов, образующих на экране прямоугольник размером 8x16.



    Попробуем подобрать узор заливки, при котором область покрывается красными штрихами длиной по четыре пиксела с шахматным расположением штрихов между строками. 0чевидно, что первые четыре байта строки-шаблона могут быть получены в виде суммы:

    M1$=CHR$(&H0)+CHR$(&H0)+CHR$(&HF0)+CHR$(&HFF)

    Первый байт подавляет биты синего цвета у всех восьми пикселов, второй -биты зеленого, третий байт формирует у первых четырех пикселов единичные биты красного цвета, сохраняя у оставшихся четырех нулевые разряды. Последний байт заносит по единице в бит яркости каждого пиксела, превращая черный цвет фона в темно-серый.

    Три следующие четверки шаблона могут состоять из одинаковых наборов вида:

    M1$=M1$+CHR$(&H0)+CHR$(&H0)+CHR$(&H00)+CHR$(&HFF) M1$=M1$+CHR$(&H0)+CHR$(&H0)+CHR$(&H00)+CHR$(&HFF) M1$=M1$+CHR$(&H0)+CHR$(&H0)+CHR$(SH00)+CHR$(&HFF)

    Пятая строка шаблона должна изменять расположение красного штриха:

    M1$=M1$+CHR$(&H0)+CHR$(&H0)+CHR$(&H0F)+CHR$(SHFF)

    Наконец, три последних четверки должны повторять зазор между строками, описанный выше:

    M1$=M1$+CHR$(&H0)+CHR$(&H0)+CHR$(&H00)+CHR$(&HFF) M1$=M1$+CHR$(&H0)+CHR$(&H0)+CHR$(&H00)+CHR$(&HFF) M1$=M1$+CHR$(&H0)+CHR$(&H0)+CHR$(&H00)+CHR$(&HFF)

    0кончательный вариант программы, в которой можно поварьировать строку заливочного шаблона, приведен ниже.

    Программа 8_10.bas

    REM Красные штрихи в шахматном порядке SCREEN 12

    I1$=CHR$(&HFF):' байт с битами повышенной интенсивности

    B0$=CHR$(&H0):' байт с нулевыми битами синего цвета

    G0$=CHR$(&H0):' байт с нулевыми битами зеленого цвета

    R0$=CHR$(&H0):' байт с нулевыми битами красного цвета

    R40$=CHR$(&HF0):' байт с битами красного-черного

    R04$=CHR$(&HF):' байт с битами черного-красного

    M1$=M1$+B0$+G0$+R40$+I1$: M1$=M1$+B0$+G0$+R0$+I1$ M1$=M1$+B0$+G0$+R0$+I1$ : M1$=M1$+B0$+G0$+R0$+I1$ M1$=M1$+B0$+G0$+R04$+I1$: M1$=M1$+B0$+G0$+R0$+I1$ M1$=M1$+B0$+G0$+R0$+I1$ : M1$=M1$+B0$+G0$+R0$+I1$



    LINE (100,100)-(200,200),,B PAINT (150,150),M1$,15 END

    Сравнительно несложная модификация этой программы позволяет изобразить фрагмент кирпичной стены:

    Программа 8_11.bas

    ' Построение кирпичной стены SCREEN 12

    I1$=CHR$(&HFF) ' байт с битами повышенной интенсивности

    B0$=CHR$(&H0) ' байт с нулевыми битами синего цвета

    G0$=CHR$(&H0) ' байт с нулевыми битами зеленого цвета

    R8$=CHR$(&HFF) ' байт с единичными Ситами красного цвета

    RL$=CHR$(&H40) ' красный бит слева

    RR$=CHR$(£H2) ' красный бит справа

    M1$=M1$+B0$+G0$+R8$+I1$: M1$=M1$+B0$+G0$+RL$+I1$

    M1$=M1$+B0$+G0$+RL$+I1$: M1$=M1$+B0$+G0$+RL$+I1$

    M1$=M1$+B0$+G0$+R8$+I1$: M1$=M1$+B0$+G0$+RR$+I1$

    M1$=M1$+B0$+G0$+RR$+I1$: Ml$=Ml$+B0$+G0$+RR$+Il$

    LINE (100,100)-(200,200),,B

    PAINT (150,150),M1$,15 END




    Содержание раздела