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

ОргЭВМ(лабы 1-5) / отчетЛаб3

.docx
Скачиваний:
102
Добавлен:
28.12.2016
Размер:
248.15 Кб
Скачать

МИНОБРНАУКИ РОССИИ

–––––––——————————–––––––

Санкт-Петербургский государственный электротехнический университет «ЛЭТИ»

————————————————————

Кафедра ИС

отчет

по лабораторной работе №3

по дисциплине «Организация ЭВМ и систем»

Тема: Исследование видеосистемы (графический режим)

Выполнили Ильичева К.

Середа И.

Факультет: КТИ

Группа № 4373

Принял Иванов Д.

Санкт-Петербург

2016 г.

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

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

1. Разработать программу для вывода на экран графика заданной функции.

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

Номер

Функция

Диапазон аргумента

Начало

Конец

6

Cos2(x/4)+Sqrt(x)

3π/2

16π

2. Произвести разметку осей и проставить истинные значения точек.

3. Найти максимальное значение функции на заданном интервале и вывести в отдельное окно на экране.

Теоретические сведения

Использование графики в языке С++ - это многошаговый процесс. Прежде всего необходимо определить тип видеоадаптера. Затем устанавливается подходящий режим его работы и выполняется инициализация графической системы в выбранном режиме. После этого становятся доступными для исполь­зования функции графической библиотеки <graphics.h> для построения основных графических примитивов: отрезков прямых линий, окружностей, эллипсов, прямоугольников, секторов, дуг и т.д., появляется возможность вывода текста с использованием различных шрифтов.

Реализация:

Начнем рассмотрение с подключения графического режима:

int driver, mode; // драйвер и режим

driver = DETECT; // автоопределение

initgraph(&driver,&mode,"c:\\borlandc\\bgi");

Инициализацию графической модели выполняет функция initgraph():

void far initgraph(int *graphdriver, int *graphmode, char * pathtodriver).

При вызове она инициализирует графическую систему, загружая. BGI-драйвер, определяемый указателем graphdriver, и устанавливая видеоадаптер в графический режим, задаваемый указателем graphmode. Третий аргумент функции initgraph() задает маршрут поиска файла, содержащего .BGI-драйвер. Если файл не найден в заданной директории, функция просматривает текущий директорий. В нашем случае маршрут задан следующим образом: "c:\\borlandc\\bgi"

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

Далее перейдем непосредственно к выводу графика заданной функции:

Две функции позволяют определить ширину и высоту экрана в пикселах для текущего видеорежима: getmaxx() и getmaxy().

Задание стиля линии выполняет функция setlinestyle().

void setlinestyle (int linestyle, unsigned upattern, int thickness)

Устанавливает стиль "рисования" отрезков прямых линий и графических примитивов. Аргумент linestyle выбирает стиль линии, а аргумент thickness - толщину линии.

Аргумент upattern используется только в том случае, когда задается отличный от предопределенных стиль линии, т.е. если linestyle равен USERBIT_LINE (4).

Что же касается функции rectangle(), то ее прототип выглядит следующим образом:

void rectangle( int left, int top, int right, int bottom)

Выводит контур прямоугольника, заданного координатами левого верхнего (left, top) и правого нижнего (right, bottom) углов. Координаты углов задаются относительно координат левого верхнего угла текущего графического окна. Контур выводится линией текущего цвета и стиля. Цвет контура устанавливается функцией setcolor(). Стиль линии задается функцией setlinestyle().

Заполнение цветом прямоугольной области выполняется с помощью функций setfillstyle и floodfill. Начнем с setfillstyle():

void setfillstyle(int pattern, int color)

Выбирает один из предопределенных стилей заполнения. Значение pattern идентифицирует стиль. Аргумент color задает цвет, используемый для пикселов по заданному шаблону. Задав стиль, перейдем к самому заполнению, выполняемому функцией floodfill():

void floodfill (int x, int y, int border)

Заполняет текущим стилем область экрана, ограниченную непрерывной линией с цветом border, начиная с точки с координатами (х, у). Функция заполняет область либо внутри замкнутой линии, либо вне ее. Это зависит от положения начальной точки: если она лежит внутри области, заполняется внутренняя область; если точка лежит вне замкнутой области, заполняется внешняя область; если точка лежит точно на линии цвета border, заполнение не производится. Заполнение начинается с начальной точки и продолжается во всех направлениях, пока не встретится пиксел с цветом border. Цвет border должен отличаться от цвета заполнения, в противном случае будет заполнен весь экран.

Построение графика функции выполняется с помощью функции drawf():

На вход подаем количество точек по оси X, для которых будет рассчитано значение функции.

Переменная dx отвечает за шаг аргумента x, шаг рассчитывается в соответствии с диапазоном аргумента, представленном в задании. Далее создан цикл, осуществляющий поиск максимума значения функции на представленном диапазоне аргумента x. После того, как максимум найден запускаем цикл отрисовки заданной функции: рассчитываем значение в каждой точке диапазона, и устанавливаем найденную точку на экран с помощью функции putpixel():

void putpixel(int x, int у, int pixelcolor)

Определяет, лежит ли пиксел с координатами (х, у) в текущем графическом окне, и, если лежит, выводит на экран пиксел, код цвета которого равен pixelcolor. В противном случае цвет пиксела не изменяется. Используя функцию putpixel(), можно "стереть" пиксел, если вывести его с кодом цвета фона. Для того, чтобы пиксел лежал в созданном окне необходимо нормировать координату значения функции, привести ее к целочисленному значению, а потом привести эту координату к соответствующим параметрами окна.

Нарисовав график функции, перейдем к отрисовке координатных осей:

За стиль координатных осей отвечает функция setlinestyle(), описанная выше. Чтобы нарисовать оси, необходимо воспользоваться функцией line():

void line( int x1, int y1, int x2, int y2)

Выводит отрезок прямой линии между двумя явно специфицированными точками (x1, y1) и (х2, у2), используя текущие цвет, стиль, толщину и режим вывода линии. Координаты (x1, y1) и (х2, у2) задаются относительно левого верхнего угла текущего графического окна. Функция не изменяет текущую позицию.

Подпись осей выполняется функцией outtextxy():

void outtextxy (int x, int y, char *textstring)

Выводит ASCII-строку текста, на начало которой указывает textstring, ис­пользуя текущие цвет, установки направления, типа шрифта и выравнивания строки. Аргументы х и у явно специфицируют новую текущую позицию, ис­пользуемую для вывода строки. Координаты X и Y измеряются относительно координат левого верхнего угла текущего графического окна.

Для разметки осей создает циклы, следующего вида:

for(i=0;i<29;++i)

line(X0+20*i,Y0-220,X0+20*i,Y0-225);

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

После построения графика и координатных осей, осталось вывести

максимальное значение функции на заданном диапазоне значений аргумента.

Максимальное значение находили в функции drawf() описанной выше. Это значение было найдено в формате float, для того чтобы вывести его была создана следующая конструкция:

Вначале используем функцию sprintf(), чтобы записать максимальное значение в массив символов:

int sprintf(char *buf, const char *format, arg-list)

Функция sprintf() идентична printf(), за исключением того, что вывод производится в массив, указанный аргументом buf.

Далее создав еще один массив (который будет содержать текст надписи, выводимой впоследствии на экран), добавим в него текст с помощью функции strcpy():

char *strcpy(char *str1, const char *str2)

Функция strcpy() используется для копирования содержимого str2 в str1. Аргумент str2 должен быть указателем на строку, оканчивающуюся нулем. Функция strcpy() возвращает указатель на str1. Если строки str1 и str2 перекрываются, то поведение функции strcpy() не определено.

Теперь “соединим” массивы с значением максимума функции и с надписью о том, что это максимальное значение. Эту операцию выполнит функция strcat():

char *strcat(char *str1, const char *str2)

Функция strcat() конкатенирует (соединяет в цепочку) строку str1 и копию строки str2. В конце модифицированной строки str1 функция устанавливает нулевой символ. Нулевой символ, перво­начально завершавший строку str1, замещается первым символом строки str2. Строка str2 остается в первоначальном виде.

Для того, чтобы эти функции работали подключаем библиотеки string.h и stdio.h. Вывод максимального значения непосредственно на экран осуществляет уже известная ранее функция outtextxy().

Т.к. функции графической библиотеки больше не нужны, следует вызвать функцию closegraph() "закрытия" графического режима и возвращения к текстовому режиму.

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

Пример работы программы:

Код программы:

#include "stdio.h"

#include "conio.h"

#include "math.h"

#include "dos.h"

#include "graphics.h"

#include "string.h"

int Xmax, Ymax, X0, X1, Y0, Y1;

float R, Rmax=0.;

void drawf(int N)

{ double x, dx=(16*3.14-3*3.14/2)/N;

int i;

for (i=0, x=(3*3.14/2); i<N; i++, x+=dx)

{

R=(float)(pow((cos(x/4)),2.0)+sqrt(x));

if(Rmax<R) Rmax=R;

}

for (i=0, x=(3*3.14/2); i<N; i++, x+=dx)

{

R=(float)(pow((cos(x/4)),2.0)+sqrt(x));

putpixel(i+X0,(Y0-(int)(R/Rmax*(float)(Y0-Y1)))/2-5,GREEN);

}

}

void main()

{ int i, N;

clrscr();

int driver, mode; // драйвер и режим

driver = DETECT; // автоопределение

initgraph(&driver,&mode,"c:\\borlandc\\bgi");

Xmax=getmaxx(); Ymax=getmaxy(); // Установили размеры экрана

X0=40; Y0=Ymax-30; // Левый нижний угол графика

X1=Xmax-30; Y1=30; // Правый верхний угол графика

N = X1-X0; // Количество точек по оси X

setlinestyle(0,1,3); // Установили параметры линий

setcolor(BLUE);

rectangle(2,0,Xmax-2,Ymax-15); // Вывели рамку

setfillstyle(SOLID_FILL, BLACK);

floodfill(20,20, BLUE);

drawf(N); // Рисуем график функции

setlinestyle(0,1,1); // Рисуем координатные оси

line(X0+20, Y0-5, X0+20, Y1-20);

line(X0-2, Y0-220, X1+15, Y0-220);

outtextxy(X0+40,Y1+40,"cos^2(x/4)+sqrt(x)"); // Подписываем оси

outtextxy(X1+3,Y0-219,"x");

for(i=1;i<23;++i) //Разметка осей координат

line(X0+20,Y0-i*20,X0+25,Y0-i*20);

for(i=0;i<29;++i)

line(X0+20*i,Y0-220,X0+20*i,Y0-225);

outtextxy(X0+23,Y0-218,"0");

outtextxy(X0+20*5,Y0-218,"4");

outtextxy(X0+20*9,Y0-218,"6");

outtextxy(X0+20*13,Y0-218,"8");

outtextxy(X0+20*17,Y0-218,"10");

outtextxy(X0+20*21,Y0-218,"12");

outtextxy(X0+20*25,Y0-218,"14");

char cRmax[10]; //Вывод максимального значения функции

sprintf(cRmax,"%f",Rmax);

char str[24];

strcpy(str,"MAX(f(x)) = ");

strcat(str,cRmax);

setcolor(BLACK);

rectangle(X0+25,Y0-5,X0+200,Y0+10); //Создание окна для максимального значения ф-ии

setfillstyle(SOLID_FILL, LIGHTCYAN);

floodfill(X0+30,Y0, BLACK);

setcolor(WHITE);

outtextxy(X0+30,Y0,str);

getch();

closegraph();

}

Соседние файлы в папке ОргЭВМ(лабы 1-5)