ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 04.07.2020
Просмотров: 3170
Скачиваний: 1
область цветом 2 до линий цвета 3. Отметим, однако, что эта про-
цедура не заполняет области, находящиеся "за углом", т.е. если
вдоль какой-либо горизонтальной или вертикальной траектории
встретилась точка, имеющая цвет границы, то все последующие точки
вдоль этой траектории не заполняются, даже если фигура имеет
причудливую форму и эти точки принадлежат внутренней части фигу-
ры. В следующем примере выводятся две перекрывающихся рамки цве-
тами циан и магента, а затем последняя рамка заполняется белым
цветом. Сегменты первой рамки, которые попадают в закрашенную
область также заполняются белым.
100 LINE (50,70)-(270,130),1,B 'рисуем рамку цветом циан
110 LINE (100,30)-(220,170),2,B 'рисуем рамку цветом магента
120 PAINT (101,31),3,2 'заполняем вторую рамку белым
Помните, что команда LINE может сама заполнить рамку, если Вы
укажете в качестве параметра 'BF', а не 'B'. Смотрите [4.4.5].
Оператор PAINT имеет "орнаментальные" возможности, которые
позволяют Вам заполнять области указанной картинкой. Элементы
орнамента, которые в режиме умеренного разрешения имеют размер 4
точки в ширину и 8 в высоту (8*8 для высокого разрешения) повто-
ряются по всей указанной области. Рисунок описывается набором
байтов, содержащих цепочку битов для последовательных рядов эле-
мента орнамента. В режиме умеренного разрешения цепочка битов
10000011 описывает 4 точки, первая из которых имеет цвет 2, сле-
дующие 2 - фоновый цвет, а последняя - цвет 3. Эта цепочка соот-
ветствует числу 131 или &H83 (см. приложение Б, в котором обсуж-
даются битовые операции в Бейсике). Обращение этой цепочки в
11000010 даст 193 (&HC1). Они могут быть объединены в элемент
орнамента шириной в 4 точки и высотой в 2 строкой CHR$(&H83) +
CHR$(&HC1). В такую строку могут включаться до 8 байтов, доводя
высоту до 8 точек. Такая строка используется в операторе PAINT
вместо цвета. Вот вывод квадрата, заполненного описанным орнамен-
том:
100 LINE (100,110)-(150,150),1,B 'рисуем рамку
110 PAINT (125,125),CHR$(&H83)+CHR$(&HC1),1 'заполняем ее
Отметим, что нерегулярности элемента орнамента могут приводить к
тому, что процедура PAINT завершается, не закончив заполнения
области. Бейсик решает эту проблему указанием параметра фона для
оператора PAINT. Если у Вас возникнут проблемы, обращайтесь к
руководству по Бейсику за деталями.
Оператор DRAW, позволяющий рисовать сложные линии, также может
заполнять области. Он обсуждается в [4.4.5]. "Текущая точка" (из
которой будет рисоваться следующий сегмент линии) должна быть
помещена внутрь области, ограниченной границей указанного цвета.
В строку оператора DRAW надо поместить кодовую букву P, за кото-
рой должен следовать код цвета закраски и код цвета границы. Для
вывода рамки цветом 1 палетты, а затем ее заполнения цветом 3
напишите DRAW "U10R10D10L10BH1P3,1". Здесь первые четыре кода
рисуют границы рамки, затем код 'BH' перемещает текущую точку
внутрь рамки, не рисуя линии, а затем код 'P' приводит к заполне-
нию рамки. Таким образом могут быть заполнены и более сложные
формы. Отметим, что необязательно при перемещении точки внутрь
области отменять рисование линии вдоль этого пути. Однако, в этом
случае надо использовать для этого сегмента код цвета, отличный
от цвета заполняемой границы.
Бейсик имеет также возможность заполнения областей экрана
заранее подготовленным изображением. Изображение может быть любо-
го размера, может быть выведено в любой позиции экрана и хранится
в массиве. Обычно, изображение создается с помощью всех доступных
средств, а затем запоминается в массиве оператором GET. Массив
может быть помещен в последовательный файл [5.4.3], из которого
программа может загрузить его и вывести изображение. Оператор GET
перечисляет координаты левого верхнего и правого нижнего угла
рамки, содержащей изображение, причем сначала идет номер столбца,
а затем номер строки для каждой пары координат. Затем должно
следовать имя массива, которое не заключается в кавычки. Напри-
мер, GET (80,40)-(120,60),ARRAY3 помещает все точки, находящиеся
внутри указанной области в массив с именем ARRAY3.
Одномерные массивы, как и все остальные, должны быть предвари-
тельно описаны оператором DIM. Массив может содержать элементы
любой точности. Для вычисления требуемых размеров массива надо
сначала определить сколько байтов потребуется для хранения изоб-
ражения. Это можно вычислить по формуле 4 + INT ((x*битовнаточку
+ 7)/8)* y. Здесь "битовнаточку" равно 1 для высокого разрешения
и 2 - для умеренного разрешения. Буквы x и y относятся к числу
точек вдоль горизонтальной и вертикальной сторон блока изображе-
ния. INT обозначает целую часть числа. Наконец, надо определить
сколько элементов массива требуется для хранения данного числа
байтов. Каждый элемент занимает 2 байта в целом массиве, но 4 -
для чисел с обычной точностью и 8 - для чисел с двойной точно-
стью.
Для получения изображения из массива и вывода его на экран
используйте оператор PUT. Этот оператор требует только координаты
левого верхнего угла области экрана, в которую будет выводиться
изображение. За координатами должно быть указано имя массива.
Например, PUT (40,30),ARRAY1 помещает изображение, левый верхний
угол которого будет находиться в столбце 40 и строке 30. Оператор
PUT может иметь еще и необязательный параметр, определяющий цвет,
которым будет выводиться изображение. Если этот параметр опущен,
то изображение будет выводиться точно в том виде, в котором оно
было записано оператором GET. Это эквивалентно записи PUT
(40,30),ARRAY1,PSET. В противном случае имеются некоторые другие
возможности. Если Вы вместо PSET укажете PRESET, то цвет 0 палет-
ты будет заменен на цвет 3 и наоборот, а цвет 1 палетты - на цвет
2 и наоборот.
Имеются еще три случая, использующие логические операции AND,
OR или XOR. Как и PRESET эти слова могут заменять PSET в приве-
денном примере. Обсуждение этих трех операций смотрите в приложе-
нии Б. Каждая операция включает сравнение битов существующей
точки на экране с битами точки накладываемого изображения. В
режиме высокого разрешения, когда на точку отводится только 1 бит
операция простая. Но в режиме умеренного разрешения, в котором на
каждую точку отводится 2 бита, могут происходить различные транс-
формации цветов.
AND устанавливает бит только если он был установлен и у точки
экрана и у точки изображения (взятой из массива). В режиме высо-
кого разрешения это означает, что точка изображения появится на
экране только если соответствующая точка экрана уже "включена".
Все остальные точки области будут выключены. В режиме умеренного
разрешения операция производится над обоими битами. Если для
точки экрана установка битов 01, а для соответствующей точки
изображения - 10, то оба бита будут сброшены и точка экрана полу-
чит код 00, что соответствует фоновому цвету.
OR устанавливает бит, если он был установлен либо для точки
экрана, либо для точки изображения. В черно-белом режиме OR нак-
ладывает изображение на существующее изображение на экране. В
цветном режиме для определения эффекта Вы опять должны прибегнуть
к вычислениям. Комбинация кодов палетты 1(01) и 2(10) дает 3(11),
также как и комбинация 0(00) и 3(11).
И, наконец, XOR устанавливает бит, если из двух сравниваемых
только один был установлен. Применение этой операции для чер-
но-белого экрана с массивом единиц дает негативное изображение (1
и 1 дает 0, а 1 и 0 - дает 1). В режиме умеренного разрешения эта
операция меняет все цвета. В результате получаем наложение двух
изображений. Но более важно, что при повторении этой операции
экран принимает в точности такой же вид, который он имел первона-
чально. При этом изображение стирается. Эта техника полезна для
мультипликации, когда над изображением дважды производится опера-
ция XOR в одной позиции, затем в соседней и т.д.
Низкий уровень.
Имеется много подходов к написанию процедур заполнения графи-
ческих объектов. Ни один из них не является идеальным, поскольку
всегда имеется конфликт между скоростью работы процедуры и слож-
ностью фигур, которые она может обрабатывать. Любая процедура,
которая заполняет область точку за точкой будет медленной, неза-
висимо от того, насколько элегантно она реализована. Имейте вви-
ду, что почти каждая модифицируемая точка расположена в байте,
все точки которого будут изменяться в тот же самый цвет. Получе-
ние доступа к одному и тому же байту с использованием сложных
процедур требует существенно больше времени, чем установка целого
байта за один доступ к ячейке видеобуфера. Например, поточечная
очистка экрана требует на IBM PC нескольких секунд при использо-
вании функции BIOS, в то время как прямой доступ в память произ-
водит эту операцию мгновенно:
MOV AX,0B800H ;ES указывает на буфер экрана
MOV ES,AX ;
MOV CX,8192 ;заполняем все байты
MOV AX,0 ;в каждый байт пишем 0
MOV DI,0 ;DI поочередно указывает на все байты
REP STOSW ;повторяем запись 8192 раза
Многие процедуры заполняют по одной горизонтальной строке,
проверяя на цвет границы справа и слева. Поскольку строки состоят
из смежных байтов данных, то надо поочередно брать байты из ви-
деобуфера и проверять присутствует ли в них цвет границы. Если
цвет границы отсутствует, то можно заменить сразу весь байт на
цвет заполнения. В противном случае к данному байту применяется
поточечный подход.
Имеется очень быстрый способ определения присутствует ли гра-
ничный цвет в данном байте видеобуфера. Предположим, что процеду-
ра ищет цвет 1 палетты в режиме умеренного разрешения с четырьмя
цветами. Этому цвету соответствует код 01, поэтому сначала запол-
ним весь байт этим кодом: 01010101. Затем используем операцию NOT
для обращения каждого бита, после чего байт примет вид 10101010.
Проделаем операцию XOR со значением взятым из видеобуфера; в
результате получим байт, у которого оба бита, относящиеся к одной
точке равны 1 только для точек, имеющих граничный цвет. Затем
снова используем операцию NOT с тем, чтобы пара битов, относящих-
ся к точке граничного цвета имела код 00. После этого используем
операцию TEST для нахождения полей со значением 00. Если такое
поле найдено, то граничный цвет обнаружен и процедура переходит к
обычному поточечному анализу данного байта. Эту процедуру можно
еще убыстрить, если использовать словные данные.
MOV AL,ES:[BX] ;берем байт из видеобуфера
XOR AL,10101010B ;устанавливаем биты для цвета границы
NOT AL ;обращаем биты
TEST AL,11000000B ;проверяем биты 7-6
JZ FOUND_BOUND ;переход если граничный цвет
TEST AL,00110000B ;проверяем биты 5-4
JZ FOUND_BOUND ;переход если граничный цвет
TEST AL,00001100B ;проверяем биты 3-2
JZ FOUND_BOUND ;переход если граничный цвет
TEST AL,00000011B ;проверяем биты 1-0
JZ FOUND_BOUND ;переход если граничный цвет
MOV AL,FILL_COLOR ;граничного цвета нет, заполняем байт
MOV ES:[BX],AL ;возвращаем байт в видеобуфер
.
.
FOUND_BOUND:
Когда это возможно, постарайтесь, чтобы границы прямоугольных
областей Ваших картинок были выравнены на границу двух, четырех
или восьми точек, с тем чтобы прямое отображение в память имело
дело с целыми байтами. Другая возможность, хотя и не столь быст-
рая, состоит в создании определяемых пользователем псевдографи-
ческих символов [4.3.4] и выводе их на границе области заполне-
ния. Короче, в данной области Вы имеете все возможности проявить
сообразительность, а зачастую стоит подумать, а нужна ли Вам
столь сложная графика в данной задаче.
4.4.7 Графический вывод с использованием символов псевдографики.
Когда Вы выводите изображение точка за точкой, то это отнимает
очень много времени, особенно когда создаются эффекты мультипли-
кации. Один из способов экономии времени состоит в сведении всех
или части выводимых форм к фигурам, которые могут быть построены
на матрице точек 8*8. Такие фигуры могут быть созданы, как опре-
деляемые пользователем символы, как показано в [4.3.4]. После
того, как эти символы определены они выводятся на экран очень
быстро и просто. Эти символы могут выводиться вперемешку с пото-
чечными графиками, как обычные буквы. Один из способов быстрого
заполнения фигуры состоит в последовательном выводе внутри фигуры
полностью закрашенного блока. Отметим, что эти символы всегда
располагаются в стандартных позициях курсора.
Средний уровень.
В этом примере рисуется фигура человека, занимающая 2 символа
в высоту и 2 символа в ширину. Как объяснено в [4.3.4] вектор
прерывания 1FH указывает на начало области данных, определяющих
символы. Четыре символа могут быть выведены обычными процедурами
DOS или BIOS. Легко создать другой набор символов, для вывода
фигуры с руками и ногами в другом месте экрана. Два набора симво-
лов могут поочередно меняться в соседних позициях курсора, созда-
вая иллюзию человека, идущего по экрану.
;---в сегменте данных
CHARACTER_DATA DB 00110000B ;левый верхний квадрант
DB 01100111B
DB 01100111B
DB 00110011B
DB 00011111B
DB 00001111B
DB 00001111B
DB 00000111B
DB 00000011B ;правый верхний квадрант
DB 10001100B
DB 10011000B
DB 00110000B
DB 11100000B
DB 11000000B
DB 11000000B
DB 10000000B
DB 00001111B ;левый нижний квадрант
DB 00011111B
DB 00011100B
DB 00011000B
DB 00011000B
DB 00110000B
DB 01100000B
DB 00010000B
DB 11000000B ;правый нижний квадрант
DB 11000000B
DB 11000000B
DB 11000000B
DB 01100000B
DB 01100000B
DB 00010000B
DB 00011110B
DB 00000000B
;---установка вектора прерывания
PUSH DS ;сохраняем DS
MOV DX,OFFSET CHAR_DATA ;смещение для данных в DX
MOV AX,SEG CHAR_DATA ;сегмент для данных в DS
MOV DS,AX ;
MOV AH,25H ;функция установки вектора
MOV AL,1FH ;номер вектора
INT 21H ;устанавливаем вектор
POP DS ;восстанавливаем DS
;---рисуем фигуру
;---позиционируем курсор на верхний ряд
MOV AH,2 ;функция установки курсора
MOV DH,13 ;строка 13
MOV DL,20 ;столбец 20
MOV BH,0 ;страница 0
INT 10H ;установка курсора
;---рисуем верхние два символа
MOV DL,128 ;берем символ 128
MOV AH,2 ;функция вывода/курсор вперед
INT 21H ;вывод символа
MOV DL,129 ;берем символ 129
INT 21H ;выводим его
;---позиционируем курсор на нижнюю строку
MOV DH,14 ;строка 14
MOV DL,20 ;столбец 20
MOV AH,2 ;функция установки курсора
INT 10H ;устанавливаем курсор
;---рисуем нижние два символа