Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

lrgraph

.pdf
Скачиваний:
17
Добавлен:
11.03.2016
Размер:
749.88 Кб
Скачать

31

Рис. 4.1

SetActivePage(номер_страницы) - для установки номера активной страницы. Необхо-

димо учесть, что нумерация страниц в графическом режиме языка TurboPascal начинается с нуля.

SetVisualPage(номер_страницы) - для установки номера видимой (отображаемой на

экране) страницы.

GetImage(x1, y1, x2, y2, память) - для сохранения изображения заданного участка эк-

рана в ОЗУ. Параметры x1, y1, x2, y2 задают координаты левого верхнего и правого нижнего

углов сохраняемого участка экрана, а память представляет собой переменную-имя буфера в ОЗУ, хранящего данное изображение.

PutImage(x, y, память, способ) - для выдачи на экран сохраненного в ОЗУ участка.

Переменная способ указывает вид объединения передаваемой на экран информации с уже

имеющейся и может принимать следующие значения:

0

MOV

1

XOR

2

OR

3

AND

4

NOT

Значение 0 (MOV) позволяет при наложении c некоторым сдвигом стереть предыдущее изо-

бражение и регенерировать его на новом месте, что создает эффект перемещения. Другие зна-

чения переменной способ позволяют создавать различные видеоэффекты.

Работа с выделенным фрагментом достаточно сложна, так как предполагает использо-

вание переменных типа Pointer (указатель) и требует предварительного определения размера выделяемого прямоугольника с помощью функции ImageSize(x1, y1, x2, y2) и резервирования в ОЗУ для него памяти с помощью процедуры GetMem(память, размер). Более подробно данный инструментарий рассмотрен в примере.

Графический режим позволят как в статике, так и в динамике выводить на экран фрагменты текста, для чего используются следующие процедуры:

32

SetTextJustify(горизонталь, вертикаль) - для выравнивания текста по горизонтали и вертикали.

горизонталь - переменная, задающая режим горизонтального выравнивания и прини-

мающая одно из следующих значений:

0 - левое выравнивание (выводимый символ располагается справа от задаваемой коор-

динаты вывода);

1 - выравнивание по центру;

2 - правое выравнивание.

вертикаль - переменная, задающая режим вертикального выравнивания и принимающая одно из следующих значений:

0 - нижнее выравнивание (выводимый символ располагается сверху по отношению к задаваемой координате вывода);

1 - верхнее выравнивание.

SetTextStyle(шрифт, направление, размер) - для установки текущих параметров выводимого текста.

шрифт - переменная, задающая тип шрифта и принимающая одно из значений в диапа-

зоне 0..4;

направление - переменная, задающая направление вывода текста (0 - по горизонтали, 1 -

по вертикали);

размер - переменная, задающая размер символов. Определяется опытным путем исходя из требований к изображению.

OutTextXY(x, y, строка) - для вывода на экран последовательности символов строка,

начиная с точки с координатами x, y.

OutText(строка) - для вывода на экран последовательности символов строка, начи-

ная с текущей позиции.

Пример программы

Задание: серповидная луна медленно уходит за горизонт. Программа реализована на основе метода выделения, сохранения и наложения сохраненного прямоугольного фрагмента для стирания старого и создания нового изображения на новом месте.

33

Листинг программы

program luna; uses

Graph, Crt; {подключение требуемых модулей} var

Driver, Mode:integer;

p:Pointer; {указатель на место расположения в памяти выделяемого прямоугольного фрагмента}

size:word; {размер выделяемого фрагмента} i:integer; {переменная цикла}

begin

Driver:=0; {автоматическое обнаружение поддерживаемого графического режима}

Mode:=0; {установка подрежима}

InitGraph(Driver, Mode, ''); {запуск графического режима}

SetBkColor(1); {установка синего цвета фона}

ClearDevice; {очистка экрана с окраской в цвет фона}

SetColor(14); {установка цвета для контура луны}

SetLineStyle(0, 0, 3); {установка типа линии: сплошная, толстая}

Arc(100, 100, 324, 36, 100); {задание первой дуги луны}

Arc(150, 100, 300, 60, 66); {задание второй дуги луны}

SetFillStyle(1, 14); {установка стиля заполнения}

FloodFill(205, 100, 14); {заполнения сектора луны желтым цветом}

Size:=ImageSize(180, 40, 220, 160); {определение размера выделяемого фрагмента}

GetMem(p, size); {выделение памяти для выделенного фрагмента экрана}

GetImage(180, 40, 220, 160, p^); {сохранение в памяти выделенного фрагмента} for i:=41 to 450 do {организация цикла для движения луны}

begin

Delay(300); {задержка на 0.3 сек. на каждом шаге}

34

PutImage(180, i, p^, 0); {стирание предыдущего изображения путем наложения фрагмента и генерация того же изображения на новом месте}

end;

Closegraph; {выход из графического режима} end.

Варианты задания

Создать программу, реализующую средствами графики языка программирования TurboPascal следующее динамическое изображение, базирующееся на задании предыдущей лабо-

раторной работы:

1)красное солнце поднимается из-за моря и перемещается вверх и вправо;

2)секундная стрелка совершает полный оборот;

3)два пузырька в стакане всплывают за 15 сек;

4)солнце вращается против часовой стрелки с дискретом 100/сек. Длина цикла 20 сек;

5)один шар из связки поднимется вверх, а второй - с удвоенной скоростью опускается вниз;

6)крюк крана двигается по стреле вправо и опускается вниз;

7)колесо вращается 15 сек с дискретом 0.5 сек, поворачиваясь на каждом шаге на 10о;

8)знак «Кирпич» постепенно (за 20 сек с дискретом 0.4сек на каждом шаге) прячется за го-

ризонт;

9)с дискретом 0.7 сек. меняется цвет светофора. Данная процедура повторяется три раза;

10)один шар на бильярдном столе движется вверх, а второй с удвоенной скоростью вправо;

11)показания термометра изменяются от -100 до 400, а затем в два раза медленней до 00;

12)окна дома разного цвета движутся навстречу друг другу и в конечном итоге меняются мес-

тами;

13) лестница перемещается справа налево, а утолщенная нижняя перекладина - за это же вре-

мя - вверх;

14)к парашюту подвешено слово «КГТУ». Все изображение опускается вниз и сносится влево с удвоенной скоростью;

15)диск телефона поворачивается на пять цифр с дискретом 2 сек;

16)на верху арки фонарь. Арка перемещается по экрану справа налево, при этом меняется цвет фонаря;

35

17)стол по синусоиде (один цикл) перемещается вдоль экрана;

18)стилизованное изображение шашки проходит по главной диагонали доски с дискретом 0.7

сек;

19)мяч перемещается снизу вверх и к концу движения уменьшается в два раза;

20)буква Н перемещается слева направо и уменьшается к концу движения в два раза;

21)на экране отображается понедельный по горизонтали календарь текущего месяца. Красная рамка перемещается по датам с дискретом 0.7 сек.;

22)на экране отображается понедельный по вертикали календарь текущего месяца. Красная рамка перемещается по датам с дискретом 1.1 сек.;

23)на экране по горизонтали нарисован спидометр до 200 км/час. Шкала доходит до 180 км за

20 сек., а затем за 15 сек. опускается до 60 км.;

24)справа налево по экрану движется стрелка, у которой хвост движется в два раза медленней начала;

25)на экране квадрат со стороной 200 пикселей. После запуска движения вертикальные сто-

роны начинают сдвигаться до превращения прямоугольника в прямую линию за 15 сек. Затем идет возврат в исходное состояние и повторение за то же время подобного движения верти-

кальных сторон; 26) на экране квадрат со стороной 300 пикселей. По часовой стрелке со скоростью 50 пиксе-

лей/сек вдоль внутренней стороны квадрата движется меньший квадрат со стороной 30 пиксе-

лей.

Выполнение лабораторной работы

1.Получить задание у преподавателя.

2.Написать и отладить программу, реализующую требуемое изображение.

3.Результат работы программы продемонстрировать преподавателю.

4.Напечатать листинг программы.

Содержание отчета

Отчет включает:

36

1)содержание задания;

2)блок-схему программы;

3)листинг программы;

Контрольные вопросы

1.Каким образом осуществляется смена графических страниц в алгоритмическом языке TurboPascal?

2.Можно ли менять высоту символов, отображаемых в графическом режиме?

3.Можно ли размещать текст вертикально по экрану в графическом режиме?

4.Можно ли использовать окна при создании динамического изображения в графическом режиме?

5.Какие предварительные операции требуются для сохранения в памяти ПК выделенного фрагмента?

Рекомендуемая литература

Смотри литературу, рекомендованную к лабораторной работе №3.

37

Лабораторная работа №5

Преобразование двумерных координат

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

Введение

Преобразования координат широко используются при синтезе как статических, так и динамических изображений с целью реализации таких операций над рисунком как перенос, поворот, подобие, симметрия. В лабораторных работах №2 и 4 движение создавалось путем переноса в системе координат, неявно существующей на экране дисплея. Перенос является достаточно простой операцией, т.к. реализуется путем изменения значений одной и/или второй координат. Другие операции, а тем более их комбинация, характеризуются большей сложностью и требуют соответствующих математических преобразований. Для простоты в данной лабораторной работе рассматриваются только двумерные преобразования. Обычно в данном процессе исходно задаются основные (первичные) координаты x1, y1, а через них в виде уравнений просчитываются вторичные координаты x22, y22.

x22 = f(x1, y1), y22 = f(x1, y1).

Наиболее распространены так называемые аффинные преобразования /1/, которые предполагают сохранение после расчета вторичных координат параллельность и формы у

прямых. Общий вид уравнений таких преобразований имеет вид

x22 = axxx1 + axyy1 + ax, y22 = ayxx1 + ayyy1 + ay.

При этом сдвиг без поворота характеризуется матрицей коэффициентов

1

0

ax

0

1

ay

где ax, ay - задают сдвиг соответственно по осям x и y, т.е. x2 = x1 + ax,

38

 

 

 

y2 = y1 + ay.

Операция масштабирования (преобразования подобия) реализуется матрицей

 

М

0

0

 

 

 

 

0

М

0

 

 

 

 

 

 

Зеркальное отображение относительно диагонали первого квадранта (смена координатных осей) предполагает матрицу вида

0

1

0

1

0

0

Повороту на угол α против часовой стрелки соответствует матрица

сosα

-sinα

0

sinαα

cosα

0

Комбинации двух или более операций преобразования соответствует комбинация ко-

эффициентов соответствующих матриц. Так, например, сдвиг с одновременным поворотом

реализуется матрицей

 

 

 

сosα

-sinα

ах

 

 

sinαα

cosα

аy

 

 

 

 

Описание среды программирования

При преобразовании координат в среде языка программирования TurboPascal необхо-

димо учесть, что графический экран ПК представляет собой четвертый квадрант прямоуголь-

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

во на величины x и/или y, т.е. реализуется локальная система, сдвинутая на данные величи-

ны относительно глобальной. В дальнейшем, глобальные координаты всех точек (xг, yг) пере-

считываются через локальные (xл, yл) по следующим уравнениям: xг = xл + x,

yг = y - yл.

Вторая проблема, возникающая обычно при сложных преобразованиях, - разная раз-

решимость (количество пикселей на единицу длины) графического экрана по горизонтали и

39

вертикали. Попытка изобразить квадрат путем задания одинакового количества пикселей по его сторонам приводит к отображению прямоугольника, вытянутого по высоте. Данный эффект отсутствует только при разрешении 640х480 и особенно усиливается при установке подрежимов с низким количеством пикселей по вертикали, например, 640х200 (см. лабораторную работу №3). Для устранения данного эффекта средствами языка Паскаль производится предварительное масштабирование изображения с помощью процедуры GetAspectRatio(mx, my),

где mx, my - переменные, в которые записывается число точек по горизонтали и вертикали. В дальнейшем, при построении требуемого изображения все координаты по оси x должны умножаться на отношение my/mx или, наоборот, все координаты по оси y умножаются на отношение mx/my. При этом возникает еще одна проблема, связанная с особенностями языка Паскаль: получаемые при умножении масштабированные координаты могут принимать вещественные значения, что запрещено для параметров графических примитивов данного языка. Поэтому все результаты таких умножений должны округляться функцией Round.

Пример программы

В первом квадранте локальной системы координат нарисовать две вертикальные параллельные линии, а затем сдвинуть их вверх и вправо на 100 пикселей и повернуть на 30о против часовой стрелки относительно начала локальных координат.

Начало локальной системы координат расположим в точке (300, 320) пикселей. Можно дополнить программу возможностью задания начала в диалоговом режиме при каждом запуске программы. Фрагмент программы, используемый для создания на экране локальной системы координат, выделен в отдельную процедуру, чтобы его можно было использовать в следующей лабораторной работе.

Листинг программы

Program Linii;

uses

Graph, Crt; var

40

GraphDriver:integer;

GraphMode:integer;

mx, my:word; {кооффициенты масштабирования}

x11, x12, x21, x22, y11, y12, y21, y22:integer; {координаты концов линий} dx, dy:integer; {сдвиг локальных координат относительно глобальных} a:real; {угол поворота}

x0, y0:integer; {величина сдвига линий в системе локальных координат}

procedure XY(xn, yn:integer); {процедура создания на экране локальных координат} begin

SetLineStyle(0,0,1); {установка стиля линий}

Line(xn, 300, xn, 50); {отображение на экране системы координат}

Line(xn, 50, xn-5, 60);

Line(xn, 50, xn+5, 60);

Line(40, yn, 600, yn);

Line(600, yn, 593, yn-3);

Line(600, yn, 593, yn+3);

SetColor(4); {установка цвета для вывода символов}

SetTextJustify(0,0); {установка стиля выравнивания текста}

SetTextStyle(0, 0, 1); {установка стиля текста}

OutTextXY(597, yn+15, 'X'); {вывод заголовка оси Х}

OutTextXY(xn-10, 50, 'Y'); {вывод заголовка оси Y} end;

begin

GraphDriver:=3; {установка графического режима EGA}

GraphMode:=1; {установка подрежима с разрешением 640x350}

InitGraph(GraphDriver, GraphMode, '' '');

SetBkColor(9); {установка светло-синего цвета фона}

ClearDevice; {закрашивание экрана цветом фона}

GetAspectRatio(mx, my); {определение коэффициентов масштабирования}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]