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

LRP2

.pdf
Скачиваний:
18
Добавлен:
02.02.2015
Размер:
520.44 Кб
Скачать

5.Особенности программирования.

5.1.На языке Турбо-Паскаль.

5.1.1.Для обращения к видеопамяти применяется предопределенный массив Mem . Например, для чтения байта по адресу A000:0000H используется выражение b:=Mem[$a000:$0000] (b переменная типа byte).

5.1.2.Для обращения к портам ПЭВМ применяются предопределенный массив Port. Например, для записи значения 3dH в порт 3c0H используется выражение Port[$3c0]:=$3d; для чтения из порта3daH используется выражение data:=Port[$3da], где data - переменная типа byte.

5.2. На языке Турбо-Си.

5.2.1. Для обращения к видеопамяти используются дальние указатели,которые объявляются в программе следующим образом:

char far * uk;-для работы с байтами.

Для чтения байта по адресу A000:0000H используется выражение :

uk=( char far * ) 0xA0000000;

b=* uk; где b-переменная типа char;

5.2.2. Для обращения к портам ПЭВМ применяются функции чтения и записи порта,которые хранятся в библиотеке < dos.h>. Библиотека подключается командой

#include < dos.h>

после чего, например, для записи значения 3dH в порт 3c0H используется выражение:

outportb(0x3c0,0x3d);

Для чтения из порта 3daH используется выражение:

data=intportb(0x3da),где dataпеременная типа char;

6.Индивидуальные задания.

По второй цифре номера студента выбрать параметры согласно таблице 7.

71

Таблица 7 ╔═════════════╦═══════════════════════════════════════╗

Параметры ║

Номер в журнале

║ 0 1 2 3 4 5 6 7 8 9 ║

║═════════════╬═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╤═══╣

║ Xn1

║30 │ 0 │ 10│ 30│50 │ 60│ 40│30 │20 │ 0 ║

║ Yn1

║ 60│ 0 │ 20│ 50│ 10│ 40│ 30│10 │40 │50 ║

║ Xk1

║260│200│250│280│300│310│210│240│290│190║

║ Yk1

║120│150│140│130│120│110│100│150│140│130║

║ L1

║ 5 │ 3 │ 4 │ 2 │ 4 │ 3 │ 5 │ 4 │ 3 │ 4 ║

║ color

║ C │ 1 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ A │ B ║

║ Xn2

║350│400│410│450│430│460│360│330│420│340║

║ Yn2

║ 0 │ 60│ 50│ 40│ 10│ 30│ 40│ 10│ 50│ 20║

║ Xk2

║580│500│600│550│630│560│680│510│520│530║

║ Yk2

║150│120│130│140│150│100│110│120│130│140║

║ color2

║ 7 │ D │ E │ F │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 ║

║ Xn3

║ 10│ 30│ 0 │ 20│ 30│ 40│ 60│ 50│100│ 90║

║ Yn3

║320│160│360│140│310│120│290│180│280│150║

║ Xk3

║630│500│400│600│580│530│420│510│620│460║

║ Yk3

║150│300│160│310│140│290│120│280│180│320║

║ L3

║ 3 │ 5 │ 4 │ 3 │ 4 │ 5 │ 3 │ 4 │ 2 │ 4 ║

║ color3

║ 1 │ 8 │ 9 │ 10│ A │ B │ C │ D │ E │ F ║

╚═════════════╩═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╧═══╝

где : Xn1,Yn1,Xk1,Yk1-координаты верхнего левого (индекс n ), и правого (индекс k) угла прямоугольника.

L1толщина линии в прямоугольнике color1цвет

Xn2,Yn2,Xk2,Yk2,color2соответствующие параметры затушевывания. Xn3,Yn3,Xk3,Yk3,L3,color3координаты,толщина и цвет наклонной

линии.

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

7.1.Тема лабораторной работы. 7.2.Цель работы.

7.3.Порядок выполнения. 7.4.Индивидуальное задание. 7.5.Текст программы. 7.6.Результаты работы программы. 7.7.Выводы.

72

Лабораторная работа N 17

СОХРАНЕНИЕ И ЗАГРУЗКА ГРАФИЧЕСКИХ ИЗОБРАЖЕНИЙ. ПЕРЕМЕЩЕНИЕ И ВРАЩЕНИЕ ОБЪЕКТА.

1. Цель работы Приобретение практических навыков в манипуляции графическими

объектами.

2.Темы для предварительной проработки

2.1.Изображений линий в графическом режиме

3.Описание работы

3.1. Сохранение и загрузка графических изображений.

3.1.1. Для адаптера CGA сохранение и загрузка графических изображений является довольно простым делом, т.к. образ изображения находится в видеопамяти дисплея, а ее содержимое легко копировать на дисковый файл. Главной проблемой при копировании в файл является необходимость введения пользователем имени файла, ввиду того, что запрос о вводе и введенное имя файла сотрут часть информации на экране. Для того, чтобы избежать этого, сохраняется в ОЗУ хотя бы 14 верхних строк изображения, чистится эта область, запрашивается имя файла и, после того, как оно будет введено, восстанавливается изображение.

При этом надо учесть,что начало видеобуфера в CGA-B800:0000,причем четные строки (начиная с 0 строки) занимают буфер со смещением от 0000H до 1F3FH, а нечетные строки со смещением от 2000H до 3F3FH. При чтении байта из четной строки параллельно считается байт из нечетной строки со смещением адреса 2000H.Если такая идеология будет выдержана при восстановлении экрана, то изображение после восстановления не будет искажено,хотя порядок следования байт в ОЗУ не совпадает с порядком в видеобуфере.

Вывод текста запроса возможен стандартными операторами вывода языка с помощью прерывания BIOS 10H.

После восстановления верхних строк изображения весь видеобуфер копируется в файл.Иногда бывает полезно скопировать часть экрана в другую область.Процедура копирования сводится к выполнению в цикле следующей операции: 1.Чтения байта из видеобуфера с учетом адресации четных и нечетных строк. 2.Прибавление постоянного смещения к адресу прочитанного байта (смешения,расстояния в видеобуфере между началом исходной области копирования. SM=(Y2-Y1)*320 +(X2-X1)/2;

73

для 16-цветной графики. где X1,Y1начало исходной области копирования. Чтобы не создавать себе проблем, необходимо позаботиться о том, чтобы координаты X1,X2 соответствовали точкам начала байта.

3.1.2. Для адаптера EGA.

Любой язык программирования имеет доступ к двум режимам чтения EGA. В режиме 0 возвращается байт, содержащийся во всех четырех плоскостях, по указанному адресу. Режим 1 ищет указанный код цвета и возвращает байт, в котором бит установлен в 1, когда соответствующая точка имеет данный цвет. Бит 3 регистра режима определяет, какой режим чтения установлен (0 = режим 0). Доступ к этому регистру

осуществляется

через

порт 3CFH, и вы должны предварительно послать

5 в порт 3CEH,

чтобы

выбрать этот регистр. Обычно все остальные би-

ты этого регистра, который можно только писать, сброшены в 0, кроме битов 0 и 1, которые определяют режим записи. Поскольку при инициализации BIOS устанавливает эти биты в режим записи 0 (так что они оба равны 0), вам нужно просто послать в этот регистр 0, чтобы установить режим чтения 0, и послать 8, чтобы установить режим чтения

1.

Режим чтения 0 требует, чтобы вы предварительно установили регистр выбора карты. Единственная задача этого регистра - установить, какая из карт битов должна быть прочитана. Поэтому в него надо послать число от 0 до 3. Этот регистр имеет адрес порта 3CFH и надо предварительно послать 4 в порт 3CEH, чтобы указать этот регистр.

Режим чтения 1 более сложен. Сначала регистр сравнения цветов должен быть заполнен цепочкой битов для кода цвета, который вы ищете. Этот код помещается в младшие 4 бита регистра; старшие четыре бита не существенны. Этот регистр имеет адрес порта 3CFH и указывается предварительной засылкой 2 в порт 3CEH. После чтения ячейки памяти возвращается байт, который имеет биты, установленные в 1 для каждой точки, имеющей нужный цвет. Однако за счет использования регистра безразличия цвета (color don't care register) один и более битов кода цвета могут при сравнении игнорироваться. Обычно 4 младших бита этого регистра установлены в 1; обнуление одного из этих битов приведет к тому, что содержимое соответствующей битовой плоскости будет игнорироваться. Например, если цепочка битов для точки 3 (бит 3) по указанному адресу равна 0110 и регистр сравнения цветов содержит значение 0010, то при сравнении будет возвращен байт, у которого бит 3 равен 0, если в регистре безразличия цветов все биты равны 1. Но если регистр безразличия цветов содержит 1011, то в байте, возвращаемом процессору, бит 3 будет равен 1.

Регистр безразличия цветов имеет адрес порта 3CFH и индексиру74

ется засылкой 7 в порт 3CEH. Старшие 4 его бита не играют никакой роли.

Ни один из этих двух режимов чтения не может дать быстрый от-

вет.

В режиме чтения 0 необходимы 4 отдельных чтения, по одному для каждой битовой плоскости. В режиме чтения 1 может потребоваться до

16 чтений, прежде чем для требуемой точки будет возвращен установ-

ленный бит,

указывающий, что эта точка имеет данный цвет. Хотя EGA

относительно

медленно выполняет данную задачу, с другими проблема

ми он справляется очень быстро.

Функция D

прерывания 10Н возвращает код цвета указанной точки.

BIOS, имеющий на плате EGA, обеспечивает работы этой функции в лю-

бом режиме дисплея.

Надо поместить номер строки (отсчитываемый от

0) в DX, а номер столбца (также отсчитываемый от 0) - в CX. Резуль-

тат возвращается в AL.

 

3.2. Вращение точки в плоскости экрана.

Вращение точки в

плоскости экрана (двумерном пространстве)

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

new_Y = Y * cos(theta) + X * sin(theta) new_X = X * cos(theta) - Y * sin(theta)

Единственной сложностью при употреблении этих формул для графических дисплеев будет тот факт, что экран дисплея не является декартовым пространством. Декартовы оси определяют 4 квадранта. Однако экран терминала представляет собой один из квадрантов, оси X и Y в котором перевeрнуты ось слева направо от верхнего угла, а ось Y-сверху вниз.

Для решения этой проблемы необходимо определить новый центр и привести в соответствие координаты X и Y экрана в координаты осей D _X и D_Y декартова пространства по выражениям :

D_X=X-X0;

D_Y=Y0-Y;

Любая точка на экране может быть использована в качестве центра, но обычно центр определяется как можно ближе к центру объекта, который мы собираемся вращать.Угол вращения следует задавать в радианах. Таким образом для вращения точки необходимо выполнить:

-"Потушить" точку, записав в нее цвет фона.

-Привести в соответствие координаты дисплея к декартовым.

75

-Повернуть точку в декартовых координатах на угол theta. -Восстановить новые координаты дисплея по выражениям:

X=D_X+X0

Y=Y0-D_Y

-Вывести точку на экран с заданным цветом.

3.3. Вращение плоской фигуры в плоскости экрана. Под объектом здесь и далее будем понимать набор сегментов прямых отрезков. Координаты крайних точек каждого отрезка содержатся в двумерном массиве чисел с плавающей точкой. Каждая строка массива содержит начальные и конечные координаты данного отрезка. Это означает, что первая размерность массива представляет собой количество отрезков, входящих в состав объекта, а вторая размерность будет равна 4 (число координат крайних точек отрезка). Например, массив, приведенный ниже

double object [3][4];

определяет объект, состоящий из 3 отрезков.

Первый

Второй

 

индекс

индекс

 

 

0

1

0

start_X1 start_Y1

1

start_X2 start_Y2

2

start_X3

start_Y3

2

3

end_X1

end_Y1

end_X2

end_Y2

end_X3

end_Y3

Определить объект - это значит разместить в массиве координаты начальных и конечных точек отрезков, составляющих объект. Например, если объект представляет собой прямоугольник с координатами 0х0 10х10, то массив, определяющий данный прямоугольник, заносятся следующие числа:

object[0][0] = 0; object[0][1] = 0; object[0][2] = 0; object[0][3] = 10;

После того, как объект определен, вы можете вращать его, используя функцию rotate_object(), по часовой стрелке ,задавая соответствующий знак theta или в противоположную сторону. При вращении объекта необходимо выполнить следующие действия:

-Изображение объекта путем организации цикла по первому индексу массива object считывания из соответствующей строки массива координат двух точек и с помощью функции line_m() изображения отрезка прямой.

76

-Организация цикла нажатия клавиши (выход из цикла при нажатии клавиши ESC ) внутри которого выполняются действия:

-"Гашение" на экране объекта, которое состоит в изображении объекта фоновым цветом.Если "гасить" объект цветом отличным от фона, то вращающаяся фигура будет оставлять за собой след.

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

оbject[i,0],object[i][1],theta,X0,Y0-для 1 точки object[i][2],object[i],[3],theta,X0,Y0-для 2 точки

-Изображение объекта с новыми координатами.

3.4.Вращение трехмерных объектов.

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

Как известно из курса инженерной графики,для отображения трехмерных координат в двумерные,используются различные виды проекций. Наиболее распространенной является изометрическая проекция, у которой ось D_Z направлена вертикально вверх, а ось D_X и D_Y повернуты на угол +120 градусов и -120 градусов соответственно.Коэффициент сжатия по всем трем осям равен 0.97 (для простаты можно взять 1. Другой проекцией является диметрическая кабинетная, у которой ось D _Z вертикально вверх,ось D_Y горизонтально влево, а ось D_X повернута на +135 градусов относительно оси D_Z ( или на -135 градусов относительно оси D_Y ).Коэффициент сжатия по осям D_Z и D_Y равен 1,а по оси D_X равен 0.5.Таким образом, учитывая особенности коордионатной системы экрана (ось X влево,А ось Y вниз),преобразование координат точки выполняется:

-для изометрической проекции

X=X0+cos(3.1418/6)*(D_Y-D_X);

Y=Y0-D_Z+sin(3.1418/6)*(D_X+D_Y);

-для кабинетной проекции

X=X0+D_Y-0.5*sin(3.1418/4)*D_X;

77

Y=Y0-D_Z+0.5*sin(3.1418/4)*D_X;

где: X0,Y0координаты центра вращения и начала декартовых трехмерных координат в плоскости экрана;

D_X,D_Y,D_Zдекартовы координаты точки;

X,Y- координаты точки на экране.

Сделав преобразование координат 2 точек отрезка можно построить проекцию каждого отрезка прямой,которые создают проекцию трехмерного объекта на экране.

Ось вращения трехмерного объекта

расположена в пространстве

произвольным образом и рассматриваются

ее

составляющие-проекции

осей вращения на координатные оси D_Z,D_Y,D_X. Поэтому рассмотрим

преобразование координат точки при вращении

вокруг соответствующей

оси.(координата оси вращения не меняется). Вращение вокруг оси Z:

D_Y=D_Y*cos(theta)+D_X*sin(theta);

D_X=D_X*cos(theta)-D_Y*sin(theta);

Вращение вокруг оси Y:

D_X=D_X*cos(theta)+D_Z*sin(theta);

D_Z=D_Z*cos(theta)-D_X*sin(theta);

Вращение вокруг оси X:

D_Z=D_Z*cos(theta)+D_Y*sin(theta);

D_Y=D_Y*cos(theta)-D_Z*sin(theta);

Трехмерный объект удобно вначале описывать в декартовой трехмерной системе координат в виде двух массивов:

-двумерный массив описаний вершин (точек ) ,в котором первая размерность соответствует числу точек,а вторая размерность равна 3 и соответствует трем координатам каждой точки D_X,D_Y,D_Z соответственно.

Например,описание пирамиды с треугольным основанием ( имеется 4 вершины), массив описания точек имеет вид:

double poin[n][3]={ 60, 00,-40, /* координаты 1 точки */ -40,-60,-40, -40, 60,-40, 00, 00, 60 }

78

-двумерный массив описания ребер (линий,в которых первая размерность соответствует числу линий,а второй индекс ( размерность равна 2 ) содержит индексы начальной и конечной точки линии.( индекс точки соответствует номеру строки в предыдущем массиве poin.

Для рассмотренного выше примера треугольной пирамиды массив описания ребер имеет вид:

int K_poin[6][2]={0,1,1,2,2,0,0,3,1,3,2,3 };

Используя рассмотренные массивы и выполнив преобразование декартовых трехмерных координат программа формирует описание объекта

в координатах экрана аналогично массиву object в

двумерном случае.

Таким образом,

при

вращении трехмерного объекта программа вы-

полняет следующие действия:

 

 

-По заданным массивам poin и K_poin формирует описание проекции

объекта на экране-object.

 

 

 

-Выводит изображение

объекта как в двумерном случае используя

описание object и функцию line_m.

 

 

-Организует цикл

ожидания нажатия

клавиши,(выход из цикла по

ESC ) внутри которого выполняются следующие действия :

-"гашение" объекта, т.е. зарисовка его цветом фона.

-Поворот точек массива poin вокруг

заданной

оси.При повороте

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

-Формирование нового значения массива object и вывод изображения на экран.

4.Порядок выполнения работы.

4.1.Написать программу,которая использует разработанные в работе 12 функции bor_m() и line_m() и выполняет следующие действия.

4.1.1.Переводит систему в графический режим.

4.1.2.С помощью функции bor_m() закрашивает часть экрана в разные цвета.

4.1.3.Копирует закрашенную часть экрана в остальную часть экрана.

4.1.4.Сохраняет полученное изображение в файл ( запрос об имени файла высвечивается в верхних 14 строках ).

4.1.5.Заполняет экран фоновым цветом.

4.1.6.Выводит и вращает плоскую фигуру, параметры которой соответствуют индивидуальному заданию.

4.1.7.Выводит и вращает трехмерный объект,параметры которого соответствуют индивидуальному заданию.

79

4.1.8.Возвращает систему в текстовый режим.

5.Особенности программирования.

5.1.На языке Турбо-Паскаль.

5.1.1.Для обращения к видеопамяти применяется предопределенный массив Mem . Например, для чтения байта по адресу A000:0000H используется выражение b:=Mem[$a000:$0000] (b переменная типа byte).

5.1.2.Для обращения к портам ПЭВМ применяются предопределенный массив Port. Например, для записи значения 3dH в порт 3c0H используется выражение Port[$3c0]:=$3d; для чтения из порта3daH используется выражение data:=Port[$3da], где data - переменная типа byte.

5.2. На языке Турбо-Си.

5.2.1. Для обращения к видеопамяти используются дальние указатели,которые объявляются в программе следующим образом:

char far * uk;-для работы с байтами.

Для чтения байта по адресу A000H:0000H используется выражение : uk=( char far * ) 0xA0000000;

b=* uk; где b-переменная типа char;

5.2.2. Для обращения к портам ПЭВМ применяются функции чтения

изаписи порта,которые хранятся в библиотеке < dos.h>. Библиотека подключается командой

#include < dos.h>

после чего, например, для записи значения 3dH в порт 3c0H используется выражение:

outportb(0x3c0,0x3d);

Для чтения из порта 3daH используется выражение: data=intportb(0x3da),где dataпеременная типа char;

6.Индивидуальные задания

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

0-изометрическая

1-диметрическая кабинетная.

В таблице 1 по второй цифре номера студента в журнале выбрать параметры двумерного и трехмерного объекта.

80

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