Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы / Labs 2004 / Lab1 / LABOR_1.DOC
Скачиваний:
29
Добавлен:
16.04.2013
Размер:
391 Кб
Скачать

Московский институт электронной техники

Кафедра ИПОВС

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

«Создание программ построения графиков в DOS и Windows»

Построение графика функции.

Для построения графика функции необходимо иметь массив значений аргумента x и массив соответствующих значений функции y. Каждой паре чисел из этих массивов на графике будет соответствовать очка. Высветив все точки графика, получим совокупность точек – точечный график. На практике мы привыкли иметь дело с графиками, изображенными в виде непрерывной кривой.

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

При отображении точек графика на экране необходимо перейти от реальных величин, в которых измеряются значения аргумента и функции к безразмерным величинам – координатам течек растра экрана. Необходимо сопоставить каждой точке реального графика в мировых координатах (x, y) точку на экране в физических или экранных координатах (n, m).

Начало экранной системы координат (0, 0) располагается в левом верхнем углу экрана. Ось n направлена слева направо, ось m – сверху вниз Рис.1. В качестве единицы длины в данной системе координат используется пиксель.

Рис.1

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

Следует также учесть, что график будет располагаться в пределах поля вывода, размеры которого обычно меньше размеров экрана. Размеры поля вывода зададим в мировых координатах (x, y) и в экранных координатах (n, m). В мировой системе координат поле вывода можно определить, задав координаты левого нижнего угла (xLeft, yBottom) и координаты правого верхнего угла (xRight, yTop). В экранных координатах поле вывода определяется аналогично, координатами левого нижнего угла (nLeft, mBottom) и координатами правого верхнего угла (nRight, mTop) как показано на Рис.2.

ось y

Ось x

Рис.2

В этом случае мировые координаты (x, y) точки A будут изменяться в пределах

Экранные координаты (n, m) точки A будут изменяться соответственно в пределах

Необходимо получить связь между мировыми (x, y) и экранными (n, m) координатами точки A . Это достигается с помощью соотношений

n = (x - xLeft)/(xRight - xLeft)*(nRight - nLeft) + nLeft;

m = (y - yBottom)/(yTop - yBottom)*(mTop - mBottom) + mBottom;

Удобно эти соотношения оформить в виде inline- функций. Приведем соответствующий фрагмент кода на языке программирования С++.

double xLeft, xRight, yBottom, yTop;

int nLeft, nRight, mBottom, mTop;

//переход от координаты x к пикселю n

inline int xn(double x){

return (x - xLeft)/(xRight - xLeft)*(nRight - nLeft) + nLeft; }

//переход от координаты y к пикселю m

inline int ym(double y){

return (y - yBottom)/(yTop - yBottom)*(mTop - mBottom) + mBottom; }

Для примера построим график синуса . Выберем следующие размеры поля вывода

Графическая библиотека BC++ под MS-DOS.

Графические средства в языке C++ и в его предшественнике – в C полностью отсутствуют. Все возможности для работы с графикой компиляторы C++ представляют в виде дополнительных библиотек графических функций, если программа работает под MS‑DOS. Если программа работает под Windows, то компилятор использует функции графического интерфейса GDI (Graphic Device Interface – интерфейс графических устройств), которые предоставляет ему система Windows. В качестве инструмента для работы с графикой будем использовать графическую библиотеку под MS‑DOS компилятора BC++ 3.1 фирмы Borland.

Для работы с графической библиотекой необходимо включить в программу заголовочный файл graphics.h.

#include <graphics.h>

Затем нужно инициализировать графическую систему. Фрагмент кода показывает, как это сделать

int mode, res, driver = DETECT;

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

if((res = graphresult()) != grOk)

{

printf("\nGraphics error: %s\n", grapherrormsg(res));

exit(1);

}

Здесь предполагается, что компилятора BC++ 3.1 находится в каталоге c:\borlandc. В конце работы графическая система отключается вызовом функции.

closegraph();

Заметим также что, необходимо настроить компилятора BC++ 3.1 для работы с графикой. Откройте основное меню IDE (Integrated Development Environment - интегрированная среда разработки) BC++ 3.1. Выберете пункт меню Options. Пройдитесь по цепочке: OptionsCompiler - Code generation, и поставьте точку перед Model Large. Затем пройдитесь по другой цепочке: OptionsCompiler - Entry/Exit Code, и поставьте точку перед DOS standard. Следующая цепочка это OptionsLinkerSettings, где надо поставить точку перед Standard DOS EXE. Наконец, последняя цепочка OptionsLinkerLibraries, где ставим крестик перед Graphics Library. В этом случае подключается графическая библиотека компилятора Borland C++ 3.1. Сохраните установки компилятора следующей цепочкой OptionsSave.

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

Программа

|

Контекст устройства

|

Драйвер устройства

|

Устройство вывода

Разберем что такое контекст устройства. С формальной точки зрения контекст устройства – это структура данных. Каждый контекст устройства связан со своим устройством вывода.

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

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

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

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

  1. Получить контекст устройства

|

  1. Установить атрибуты рисунка

|

  1. Создать и выбрать графические инструменты

|

  1. Вызвать функции рисования

|

  1. Освободить и уничтожить графические инструменты

|

  1. Освободить контекст устройства

Использование контекста устройства в DOS и Windows имеет отличия. Об этом мы скажем позже, когда будем рассматривать графику в Windows. Сейчас же мы рассматриваем графику в DOS.

Пункт 1) получение контекста устройства – соответствует инициализации графической системы с помощью функции initgraph() .

Пункт 6) освобождение контекста устройства – соответствует выключению графической системы с помощью функции closegraph() .

Пункты 2) и 5) подробно рассмотрим позже в графике под Windows. Сейчас без них можно обойтись.

В пункте 3) создание и выбор графических инструментов – мы выбираем перья и кисти разной толщины, стиля и цвета которыми будем рисовать графические объекты.

В пункте 4) вызов функций рисования – мы вызываем графические функции для рисования графических объектов.

Покажем выбор пера на примере фрагмента кода

setlinestyle(SOLID_LINE, 0, 1);

setcolor(LIGHTCYAN);

Здесь выбирается перо со следующими свойствами.

стиль - сплошной

толщина линий - 1 пикселя

цвет линий - ярко-голубой

Этим пером можно рисовать линии, прямоугольники, окружности, дуги и т.д.

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

line(n1, m1, n2, m2) – рисует линию между точками (n1, m1), (n2, m2) в экранной системе координат.

moveto(n1, m1) – устанавливает указатель текущей позиции в точку с координатами (n1, m1).

lineto(n2, m2) - рисует линию между текущей точкой и точкой с координатами (n2, m2).

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

rectangle(n1, m1, n2, m2) – рисует прямоугольник по координатам (n1, m1), (n2, m2) противоположных углов.

Покажем выбор кисти на примере фрагмента кода

setfillstyle(SOLID_FILL, BLUE);

Здесь выбирается кисть со следующими свойствами.

стиль закраски - сплошной

цвет закраски - синий

Этой кистью можно закрашивать различные замкнутые фигуры.

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

bar(n1, m1, n2, m2) - рисует закрашенный прямоугольник пером и кистью выбранными выше.

Для рисования закрашенного сектора подойдет функция.

pieslice(n, m, angl1, angl2, radius) – рисует закрашенный сектор круга с центром в точке (n, m) , между углами angl1, angl2 (углы в градусах), радиусом radius .

Экранная система координат Рис.1. по умолчанию привязана ко всему пространству видеодисплея. Однако на экране можно выделить окно меньшего размера и сделать его активным. В результате экранные координаты будут привязаны к этому окну, и вывод графики будет теперь осуществляться относительно этого активного окна Рис.3. Для создания активного окна имеется функция.

setviewport(n1, m1, n2, m2, clip) – устанавливает активное окно экрана для вывода изображений.

Рис.3

Кроме рисования фигур в окне вывода и в поле вывода надо уметь рисовать текстовые надписи. Например, надпись “Hello” можно вывести в окне в точке с координатами (n, m) с помощью фрагмента кода.

char *str = “Hello”;

outtextxy(n1, n2, srt);

Если же надо вывести число, например 10.25 , то это можно сделать с помощью фрагмента кода

char *ss;

float f = 10.25;

sprintf(ss,"%3.2f",f);

outtextxy(n, m, ss);

Пример программы построения графика в dos

Приведем код программы строящей график функции . Пусть код программы находится в файле GraphDos.cpp

//строим график функции в DOS

#include <stdio.h>

#include <conio.h>

#include <graphics.h>

#include <process.h>

#include <math.h>

//размеры поля вывода в мировых координатах

double xLeft, xRight, yBottom, yTop;

//размеры поля вывода в экранных координатах

int nLeft, nRight, mBottom, mTop;

//переход от x к пикселю n

inline int xn(double x){

return (x - xLeft)/(xRight - xLeft)*(nRight - nLeft) + nLeft; }

//переход от y к пикселю m

inline int ym(double y){

return (y - yBottom)/(yTop - yBottom)*(mTop - mBottom) + mBottom; }

//создаем окно вывода

void CreatWindow()

{

int winLeft = 50, winRight = 550, winBottom = 430, winTop = 100;

setfillstyle(SOLID_FILL,3);

bar(winLeft, winTop, winRight, winBottom);

setcolor(12);

outtextxy(winLeft+5, winTop+7, "Korneev V");

setcolor(15);

outtextxy(winLeft+150, winTop+7, "Graphics to DOS");

setcolor(15);

rectangle(winLeft+3, winTop+17, winRight-3, winBottom-3);

setfillstyle(SOLID_FILL,LIGHTGRAY);

bar(winLeft+5, winTop+19, winRight-5, winBottom-5);

setviewport(winLeft+5, winTop+19, winRight-5, winBottom-5,1);

}

void main()

{

//размеры поля вывода в мировых и экранных координатах

xLeft = -2; xRight = 10; yBottom = -2; yTop = 2;

nLeft = 100; nRight = 350; mBottom = 250; mTop = 50;

//создаем массивы точек для аргумента x и функции y = sin(x)

const int N = 50;

double corX[N], corY[N];

double x, y, dx = (xRight - xLeft)/(N-1);

for(int i=0; i<N; i++)

{

x = xLeft + dx*i; y = sin(x);

corX[i] = x; corY[i] = y;

}

//инициализация графической системы

int mode, res, driver = DETECT;

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

if((res = graphresult()) != grOk) {

printf("\nGraphics error: %s\n", grapherrormsg(res));

exit(1); }

//создаем окно вывода

CreatWindow();

//оформляем поле вывода

//выбор кисти: 1) стиль - сплошной

// 2) цвет закраски - синий

setfillstyle(SOLID_FILL,BLUE);

bar(nLeft,mBottom,nRight,mTop);

//выбор пера: 1) стиль - сплошной

// 2) толщина линий - 3 пикселя

// 3) цвет линий - желтый

setlinestyle(SOLID_LINE,0,3);

setcolor(YELLOW);

rectangle(nLeft,mBottom,nRight,mTop);

//рисуем координатные оси

//выбор пера: 1) стиль - сплошной

// 2) толщина линий - 1 пикселя

// 3) цвет линий - ярко-голубой

setlinestyle(SOLID_LINE,0,1);

setcolor(LIGHTCYAN);

int nb, ne, mb, me;

nb = xn(xLeft); mb = ym(0);

ne = xn(xRight); me = ym(0);

line(nb,mb,ne,me);

nb = xn(0); mb = ym(yBottom);

ne = xn(0); me = ym(yTop);

line(nb,mb,ne,me);

//название графика и осей

setcolor(15);

outtextxy((nLeft+nRight)/2-30, mTop+25, "Y = sin(X)");

outtextxy(nLeft-35, (mBottom+mTop)/2, "Y");

outtextxy((nLeft+nRight)/2, mBottom+25, "X");

//выводим числа вдоль осей

char ss[10];

sprintf(ss,"%6.1lf",xLeft);

outtextxy(nLeft-30,mBottom+7,ss);

sprintf(ss,"%6.1lf",xRight);

outtextxy(nRight-30,mBottom+7,ss);

sprintf(ss,"%6.1lf",yBottom);

outtextxy(nLeft-55,mBottom-7,ss);

sprintf(ss,"%6.1lf",yTop);

outtextxy(nLeft-55,mTop+3,ss);

//рисуем график по двум массивам

setcolor(12);

nb = xn(corX[0]); mb = ym(corY[0]);

moveto(nb,mb);

for( i=1; i<N; i++)

{

nb = xn(corX[i]); mb = ym(corY[i]);

lineto(nb,mb);

}

getch();

//выключение графической системы

closegraph();

}

После компиляции и компоновки получаем исполняемый файл GraphDos.exe . Запускаем программу. На Рис.4 приведен результат работы программы

Рис.4

Соседние файлы в папке Lab1
  • #
    16.04.20136 Кб23EGAVGA.BGI
  • #
    16.04.201345 Кб23GRAPHDOS.EXE
  • #
    16.04.201328 Кб24GRAPHWIN.EXE
  • #
    16.04.2013391 Кб29LABOR_1.DOC
  • #
    16.04.201312 Кб24ONLYWIN.EXE
  • #
    16.04.2013128 б25Readme.txt