Знакомимся с графикой


Подключение графики

          Многие просто не понимают графику в языках программирования, говоря что-нибудь типа "Гораздо легче взять и просто нарисовать всё это в любом редакторе - и никаких заморочек!". Но тут есть свои плюсы и минусы - и это просто возможность рисования того или иного объекта. Например, в графическом редакторе мы можем нарисовать практически что угодно, а в программе можем быстро создать такие элементы, на которые уйдёт много времени в графическом редакторе, к тому же будет возможность быстрого внесения изменения в рисунок и прочего.

          Прежде всего, рассмотрим включение графического режима. При стандартном выполнении программы, активен текстовый режим - экран разделён на сорок или восемьдесят позиций и 25 или 50 строк. Есть ещё такое понятие - псевдографика - когда все фигуры формируются из текстовых символов разного цвета. Давайте не будем останавливаться на этом и перейдём к нормальной (нормальной для бейсика с паскалем). Итак, для задания графического режима экрана в бейсике используется оператор SCREEN с номером режима. Этот оператор включается только один раз и, в зависимости от номера, устанавливает определённое разрешение экрана. Посмотрим на возможные режимы экрана в бейсике в зависимости от числа после оператора SCREEN (информация вззята из файла помощи по qbasic - для различных видеоадаптеров. Кажется, сейчас все режимы работают нормально, а вот раньше работали только строго определённые видеоадаптером режимы. Таблица чуть-чуть не полная - я выписывал только самое основное. Хотите подробностей - посмотрите в справке qbasic - графические режимы):

MDPA, CGA, Hercules, Olivetti, EGA, VGA или MCGA адаптеры
SCREEN 0
Текстовый режим
40x25 или 80x25 формат текста, 8x8 формат символа
16 или 64 цвета назначаются любому из 16 атрибутов
8 страниц видеопамяти
CGA, VGA, EGA или MCGA адаптеры
SCREEN 1
320x200 графический режим
40x25 формат текста, 8x8 формат символа
16 фоновых цветов и один из двух наборов 3 цветов переднего плана, присвоенных оператором COLOR с CGA
16 цветов назначаются 4 атрибутам с EGA или VGA
1 страница видеопамяти
SCREEN 2
640x200 графический режим
80x25 формат текста, 8x8 формат символа
16 цветов назначаются 2 атрибутам с EGA или VGA
1 страница видеопамяти
Hercules, Olivetti или AT&T адаптеры
SCREEN 3
720x348 графический режим
80x25 формат текста, 9x14 формат символа
2 страницы видеопамяти
Оператор PALETTE не поддерживается
SCREEN 4
640x400 графический режим
80x25 формат текста, 8x16 формат символа
1 из 16 цветов присвоен цвету переднего плана (определяется оператором COLOR); фон - неизменно чёрный
1 страница видеопамяти
Оператор PALETTE не поддерживается
EGA или VGA адаптеры
SCREEN 7
320x200 графический режим
40x25 формат текста, 8x8 формат символа
Присвоение 16 цветов любому из 16 атрибутов
8 страниц видеопамяти
SCREEN 8
640x200 графический режим
80x25 формат текста, 8x8 формат символа
Присвоение 16 цветов любому из 16 атрибутов
4 страницы видеопамяти
SCREEN 9
640x250 графический режим
80x25 или 80x43 формат текста, 8x14 или 8x8 формат символа
64 цвета назначаются 16 атрибутам
2 страницы видеопамяти
EGA или VGA адаптеры, только монохромные мониторы
SCREEN 10
640x350 графический режим
80x25 или 80x43 формат текста, 8x14 или 8x8 формат символа
Вплоть до 9 псевдоцветов назначаются 4 атрибутам
2 страницы видеопамяти
VGA или MCGA адаптеры
SCREEN 11
640x480 графический режим
80x30 или 80x60 формат текста, 8x16 или 8x8 формат символа
Присвоение вплоть до 256K цветов 2 атрибутам
1 страница видеопамяти
SCREEN 12
640x480 графический режим
80x30 или 80x60 формат текста, 8x16 или 8x8 формат символа
Присвоение вплоть до 256K цветов 16 атрибутам
1 страница видеопамяти
SCREEN 13
320x200 графический режим
40ч25 формат текста, 8x8 формат символа
Присвоение вплоть до 256K цветов 256 атрибутам
1 страница видеопамяти

          Странно - по непонятной мне причине, отсутствуют режимы 5 и 6... Ладно. Главное, что лучше всего использовать режим номер 12 - он самый лучший по характеристикам, хотя его разрешение экрана для нас будет маловато. Для нас будет, а для бейсика - в самый раз! Оператор SCREEN 12 желательно ставить в первых строках программы, хотя можно настроить программу так, чтобы графический режим включался в ходе программы (IF ... THEN SCREEN 12), когда это надо. Вот с настройкой графического режима в паскале я так до конца и не разобрался. Я до сих пор не помню, как его правильно устанавливать, хотя в тетрадке у меня было записано...

          Этот фрагмент программы инициализирует графический режим в паскале, после него можно начинать "рисовать". Кстати, оператор CloseGraph "закрывает" графический режим, его можно писать, а можно и не писать.

          А чем рисовать-то? Уж не курсором-ли? Нет, графическими примитивами - линиями, окружностями, прямоугольниками и т.д. Так чего же мы ждём? Ноги в руки - и вперёд!

Вверх

Примитивы: Точки

          Самый первый из графический примитивов - это точка. Для "рисования" точки в бейсике используется оператор PSET со следующим синтаксисом: PSET (X,Y),C - X - координата Икс, Y - координата Игрек, C - цвет точки. После выполнения этого оператора, интерпритатор ставит точку (пиксель) заданного цвета в заданных координатах (не забыли, что ось Игрек направлена вниз?). Паскаль рисует точку при выполнении оператора "PutPixel (X,Y,C);". Кстати, вот таблица стандартных цветов (всего-навсего 16 штук!) - и в бейсике и паскале на удивление одинаковая:

Номер
Цвет
Номер
Цвет
0
чёрный
8
серый
1
синий
9
светло-синий
2
зелёный
10
светло-зелёный
3
бирюзовый
11
светло-бирюзовый
4
красный
12
светло-красный
5
малиновый
13
светло-малиновый
6
коричневый
14
жёлтый
7
светло-серый
15
белый

          Также сразу скажу пару слов о задании цвета фона, так как чёрный цвет смотрится как-то мрачно. Цвет фона задаётся оператором COLOR (им, кстати, задаётся также и цвет текста). Пишется так: "COLOR цвет_текста, цвет_фона".

          Одними точками просто так ничего не нарисуешь (конечно, вы можете попытаться, только вот сколько времени у вас это займёт?), так что идём дальше.

Вверх

Примитивы: Отрезки и прямоугольники

          "Почему эти два примитива в одном разделе" - спросите Вы. Всё просто - в бейсике, чтобы нарисовать прямоугольнк, можно задать его два противоположных угла, задав координаты конца и начала отрезка. Таким образом, чтобы нарисовать просто отрезок в бейсике нужен оператор LINE. Пишется он так: "LINE(X1,Y1)-(X2,Y2), C". Думаю, всё понятно - в первых скобках координаты начала отрезка, во вторых - конца; C - цвет. Бейсик нарисует простой отрезок заданного цвета. А вот если поставить букву B (не русскую в, а b, конечно же!) через запятую после цвета, то наш отрезок станет диагональю прямоугольника. Теперь на экране будет прямоугольник, а его диагонали видно не будет. Естественно, стороны нового прямоугольника будут параллельны экрану.

!

Будьде внимательны с координатами диагонали! Помните, что вы задаёте координаты диагонали, а не координаты сторон прямоугольника! Просто довольно часто многие делают такую ошибку.

          Ах да, если вместо "B" поставить "BF", то новый прямоугольник будет закрашенным. LINE (X1,Y1)-(X2,Y2), C, BF - нарисуется закрашенный C цветом прямоугольник с координатами диагонали X1,Y1 и X2,Y2. А если хотите сделать фигуру с непереллельными экрану сторонами, то делайте это простой последовательностью операторов LINE безо всяких там B тем более BF. (:

          В паскале мы рисуем отрезки и прямоугольники двумя разными операторами - Line и Rectangle. Но расскажу я Вам сначала не о них. Оператор SetColor позволяет устанавливать текущий цвет, который устанавливается в скобках - "SetColor(C);". Не забывайте ставить этот оператор перед рисованием чего-либо. Вернёмся к нашим баранам. В скобках после оператора Line ставятся все координаты - начала и конца - через запятую - "Line (x1,y1,x2,y2);". С оператором Rectangle - та же история - "Rectangle (x1,y1,x2,y2);" - в скобках - координаты диагонали. Вот так-то! Идём дальше.

Вверх

Примитивы: Окружности и эллипсы с дугами

          Итак, рисуем окружности. И рисуем их мы оператором Circle. В бейсике - "CIRCLE (x,y), r, c", в паскале - "Circle (x,y,r);". Как Вы уже поняли, x и y - координаты центра окружности, r - её радиус, c - естественно, цвет (не забыли про SetColor в паскале?). Например, мы пишем так: "CIRCLE (100,248), 75, 4" - бейсик нарисует красную окружность с центром в точке (100,248), радиусом в 75 точек (пикселей). Думаю, с этим проблем не возникнет... Давайте теперь разберёмся с эллипсом. Вот тут пути бейсика и паскаля расходятся. У первого эллипс задаётся в том же операторе CIRCLE (заодно расскажу про коэффициент сжатия, который равен отношению радиуса по Y на к радиусу по X. Вот, в общем-то и рассказывать больше нечего...) - "CIRCLE (X,Y),R,C,,,K" - как всегда - X и Y - координаты центра, R - радиус окружности (как бы основной!), C - цвет, а K - значение коэффициента сжатия (тут играют роль два радиуса - см.выше). ...так давайте же разберёмся заодно и с тремя лишими запятыми, которые взялись, казалось бы, ниоткуда. А вот, на самом деле, откуда - между ними можно вписать начало и конец дуги (углы - любая дуга начинается и заканчивается с определённых углов!). Идём сначала - "CIRCLE (X,Y),R,C,a,b,K" - всё остаётся на своих местах, только a и b - это те самые углы начала и конца дуги. Потренируйтесь с этим оператором, введя все параметры.

          В паскале, как я уже сказал, эллипсы рисуются по-другому. "Формула" эллипса в паскале: "Ellipse (X,Y:integer; StAngle, EndAngle, Xradius, Yradius: Word);" - X и Y - координаты центра, Integer - целые, StAngle - начальный угол (для дуги), EndAngle - конечный угол (опять же - для дуги), Xradius и Yradius - радиучы эллипса (последние четыре величины типа Word - беззнаковые целые). Опять же, попрактикуйтесь с построением окружностей, дуг и эллипсов. Попрактиковались? Идём дальше.

Вверх

Закраска

          С примитивами вроде разобрались. Но одними линиями дело не обойдётся... Давайте научимся закрашивать их. Итак, в бейсике оператор закраски - это "PAINT (X,Y), C1, C2" - где X и Y - это координаты точки закрашивания, которая лежит внутри закрашиваемого контура; C1 - цвет закраски, а C2 - цвет собственно контура. А вот и правил закраски:
  • Контур должен быть замкнут, инача закрасится весь экран - "утечка краски".
  • Контур должен быть одноцветен. Если в контуре хотя бы один пиксел будет не того цвета, который задан, то компьютер поймёт это как разрыв и опять же - закрасит весь экран.
  • Координатры закраски должны лежать внутри контура.
          Да, рекомендуется закрашивать контур сразу после его нарисования. Просто иногда сначала рисуют все контуры, а потом делают закраску - а это не всегда приводит к желаемому результату. Также если точка, указанная в скобках, попала на контур, то ничего не закрасится. Если Вы не уверены, куда ставить точку закраски, то лучше поставьте точку PSET в месте, где Вы хотите закрасить область, затем посмотрите, действительно ли эта точка находится внутри области. Если да, то смело заменяйте оператор PSET на PAINT и красьте!

Вверх

Бейсик: Макроязык GML

          Для расширения возможностей рисования графики в бейсике был разработан специальный макроязык GML (Graphics Macro Language), который позволяет строить довольно сложные изображения и выводить их на экран. Каждая команда языка представлена латинской буквой, после которой следует один или два числовых параметра (чаще всего целых). Здесь показаны эти самые буквы (которые команды!):
Команда
Действие
U,D,L,R,E,F,G,H
Переместиться в точку в соответствии со стрелкой (выше)
M x,y
Переместиться в точку с координатами x,y
M +/-n, +/-m
Переместиться по отношению к текущей позиции на +/-n точек по оси X и на +/-m точек по оси Y. Знаки плюс и минус проставлять обязательно
At
Поворот изображения против часовой стрелки вокруг точки, с которой начиналось рисование на 90 градусов*t (t=0/1/2/3). Действует во всех дальнейших командах до нового назначения
Cn
Задание нового цвета. Действует во всех дальнейших командах до нового назначения
Sn
Расстояние, указанное в командах перемещения, умножается на n/4 (0<=n<=255)
B
Переместиться в новую позицию при помощи следующих за B команд, но рисования не производить. Может предшествовать любой команде перемещения
N
Выполнить следующую команду перемещения и вернуться в исходную позицию. Может предшествовать любой команде перемещения
P c1,c2
Команда заполнения контура цветом; c1 - цвет заполнения, c2 - цвет контура. Должны соблюдаться все вышеизложенные правила закраски, и курсор должен находиться внутри закрашиваемого контура

          Для использования этих команд языка GML используется оператор DRAW. Например, команда DRAW "R50 D50 L50 U50" изобразит нам квадрат, начиная от последней графической точки. Потренируйтесь и разберитесь, что к чему. Идём дальше.

Вверх

Вывод текстовой информации в графике

          Часто хочется помимо графических изображений ещё и что-нибудь написать. Смелее - Вы уже знаете операторы LOCATE и PRINT (как и GotoXY и Write/WriteLn).

!

Только помните, что координаты в операторе LOCATE не графические (пиксели), а текстовые (символы)!

Вверх

Анимация

          Движение тоже можно реализовать - для этого используем такую конструкцию: цикл, в котором сначала рисуется объект, затем небольшая пауза (чтобы мы увидели этот объект - иначе всё произойдёт слишком быстро, никакого движения не будет), затем тот же объект рисуем чёрным цветом (или цветом фона), чтобы скрыть "предыдущий кадр" (хотя, можно и не скрывать - тогда наш объект будет просто размножаться - появится своеобразный шлейф). Можно также добавить оператор условия, чтобы, допустим, если так, то круг "пойдёт" сюда а если так, то туда.

          Чтобы сделать паузу, нужен оператор SLEEP, после которого задаётся количество секунд паузы. Если это количество не указать, то компьютер просто будет ждать нажатия любой кнопки. Самое интересное, что оператор SLEEP "понимает" только целые числа, то есть нельзя задать паузу в полсекунды или одну десятую секунды, только одну, две, три и т.д. секунды. Есть ещё один способ создания пауз, я даже его называю "генератором пауз". Это, как бы вы думали, что? Звук! Высокочастотный звук не слышен человеческому уху, и когда он звучит, другие операторы не выполняются. Так вот, исполняя оператор SOUND, динамик компьютера "пищит" на заданной частоте заданное количество тактов (а в секунде примерно 18,2 тактов). SOUND 5000, 18 - произнесётся звук частотой 5000 герц, и звучать он будет одну секунду. Кстати, динамик компьютера способен воспроизводить звуки частотой от 37 до 32767 герц. Ну вот, теперь Вы ещё и научились создавать звуки. Попрактикуйтесь - должно быть весело! (:

          Теперь рассмотрим пример движения круга слева направо по экрану (бейсик):
          Давайте разберёмся. Сначала, после очистки экрана, включается режим 12 (640x480). Затем определяется Y центра окружности - 240 - центр вертикали. Затем в цикле X от 50 до 590 (по 50 от каждого края экрана) рисуется окружность радиусом 50 зелёного цвета. Потом, после паузы в одну секунду, рисутеся такая же окружность чёрного цвета, которая закрывает собою предыдущую окружность. Потом - следующий виток цикла, окружность смещается на 1 точку вправо, всё происходит заново, таким образом, мы видим, что наша зелёная окружность "плывёт" по экрану по горизонтали (правда, медленно! для этого советую зажать какую-нибудь клавишу - будет немного побыстрее).

Вверх

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

          Анекдот. Подходит как-то один программист к другому и говорит: "Слушай, мне нужен генератор случайных чисел!", на что второй тут же отвтеил: "28!".

          Так вот, нетрудно догадаться, что делает этот самый генератор. Конечно, из этого словосочетания "генератор случайных чисел" в уме складывается что-то вроде этого:

          Конечно, я немного преувеличил... (: На самом деле, конечно же, он выглядит совершенно не так. Точнее сказать, он никак не выглядит, он просто есть. Так вот, генератор случайных чисел "производит" случайные числа - просто произвольные. Ладно, ближе к делу. Инициализация генератора случайных чисел (давно пора называть его просто ГСЧ, так и будем называть его в дальнейшем) выглядит следующим образом: RANDOMIZE TIMER в бейсике и просто Randomize; в паскале. Почему TIMER? Потому что в качестве основы для создания какой-либо последовательности случайных чисел, служат показания встроенного в компьютер таймера. Обычные операторы RND и Random генерируют случайное число от 0 до 1 (минимум 0,0000001, максимум 0,9999999 - мы видим, что вариантов просто море). Но, к примеру, нам нужно случайное число от одного до пяти - как это сделать? Очень просто. Вспоминаем функцию INT - она будет выделять целую часть из произвольного дробного числа. Дальше - в скобках после RND и Random ставится число, на которое будет умножаться это самое число от 0 до 1. Итак, Вы запомнили это, теперь забудьте! Просто запомните, что число в скобках n будет давать произвольно число от 0 до n-1, то есть, первые n чисел. То есть, если у нас такая строка: X=INT(RND(7)), то будет сгенерировано целое число от 0 до 6 включительно. Естественно, чтобы сделать число от 1 до 5, нужно написать INT(RND(5))+1. Например, RND сгенирировал случайное число - 0,54389, затем это число умножается на 5, получается 2,71945, потом выделяется целая часть - 2, и к ней прибавляется 1. Получается 3. Попало в диапозон? Конечно попало! Естественно, формулы с участием RND и Random можно "запихивать" в параметры операторов.

          А зачем, собственно, ГСЧ делает в разделе "графика"? Всё просто - его можно наглядно использовать в графике. Например, классический пример - звёздное небо. Задаём цикл от 1 до того количества звёзд, которое мы хотим, затем в нём просто пишем: "PSET (INT(RND(640))+1, INT(RND(480))+1), 7". В результате получится звёздное небо - чёрный фон и белые точки, произвольно появляющиеся каждый раз... Можно произвольно задавать цвет фигур (от 0 до 16), радиус, координаты, и так далее. Потренируйтесь, Вам должно понравиться! Можно также потренироваться с простыми числами - создать программу кидания кубика, а также бросания монеты. Это на ваше усмотрение - случайные числа часто используются.

          Таким образом, мы разобрали графику в бейсике и паскале. Идём в следующий раздел.

Перейти к решению задач
Вверх
Hosted by uCoz