Министерство общего и профессионального образования Российской Федерации РОСТОВСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ КАФЕДРА ...
9 downloads
277 Views
466KB Size
Report
This content was uploaded by our users and we assume good faith they have the permission to share this book. If you own the copyright to this book and it is wrongfully on our website, we offer a simple DMCA procedure to remove your content from our site. Start by pressing the button below!
Report copyright / DMCA form
Министерство общего и профессионального образования Российской Федерации РОСТОВСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ КАФЕДРА ТЕОРЕТИЧЕСКОЙ И ВЫЧИСЛИТЕЛЬНОЙ ФИЗИКИ _______________________________________________________________
Т. П. Шестакова МЕТОДИЧЕСКИЕ УКАЗАНИЯ по курсу "Программирование и вычислительная физика" Часть V Создание и использование модулей в языке Turbo Pascal. Работа с экраном и графикой
г. Ростов-на-Дону 2003 г.
2
Печатается по решению учебно-методической комиссии физического факультета. Протокол N от Шестакова Т. П. Методические указания по курсу "Программирование и вычислительная физика". Часть V. Создание и использование модулей в языке Turbo Pascal. Работа с экраном и графикой. Заказ N
3
ВВЕДЕНИЕ В пятой части методических указаний рассматриваются создание и использование модулей, стандартные модули, расширяющие возможности языка Turbo Pascal, структура модулей, процедуры и функции модуля CRT, управляющие выводом на экран в текстовом режиме, переход в графический режим и некоторые процедуры и функции модуля GRAPH, необходимые для построения двумерных графиков функций. СОЗДАНИЕ И ИСПОЛЬЗОВАНИЕ МОДУЛЕЙ В языке Turbo Pascal появилась возможность выделять части программы в так называемые модули, которые компилируются отдельно от основной программы. В первую очередь это относится к описанию используемых в основной программе констант, типов данных, процедур и функций. Благодаря тому, что модули компилируются отдельно от основной программы, они обладают двумя важными преимуществами. Во-первых, код программы при компиляции помещается в отдельный сегмент оперативной памяти компьютера. Длина сегмента составляет 64 Кбайт, поэтому длина программы ограничена. В то же время при использовании модулей каждый модуль помещается в отдельный сегмент памяти, что дает возможность писать большие программы. Во-вторых, некоторые типы данных, процедуры и функции могут использоваться при написании самых разных программ. Использование модулей позволяет создавать библиотеки процедур и функций. При написании программ не возникает необходимости описывать эти процедуры и функции каждый раз заново, остается только подключить к программе модуль, содержащий их описание. Стандартные модули языка Turbo Pascal: SYSTEM системный модуль, который содержит описание всех стандартных процедур и функций языка Turbo Pascal. Этот модуль автоматически подключается к любой программе и не требует специального объявления в программе с помощью слова uses (см. ниже). CRT содержит процедуры и функции, управляющие выводом на экран в текстовом режиме (например, позволяющие устанавливать цвет фона и текста, очищать экран, помещать курсор в определенную позицию экрана), а также некоторые другие (например, управляющие звуковыми сигналами).
4
GRAPH
содержит процедуры и функции, управляющие работой экрана в графическом режиме (в том числе позволяющие создавать на экране изображения различных геометрических фигур, выводить на экран текстовые надписи специальными шрифтами и т. д.). DOS содержит процедуры и функции, открывающие доступ к средствам операционной системы MS-DOS. PRINTER содержит процедуры и функции, позволяющие выводить текст на матричный принтер. OVERLAY обеспечивает возможность исполнения особенно больших программ, которые не помещаются целиком в оперативной памяти. Такие программы разбиваются на модули, и в оперативную память помещается не вся программа целиком, а лишь та ее часть (модуль), содержащая процедуры и функции, которые выполняются в данный момент. В следующий момент времени этот модуль выгружается из оперативной памяти, а на его место загружается другая часть программы. Это называется механизм оверлея (перекрытия). TURBO3, введены для совместимости с ранней версией языка Turbo Pascal GRAPH3 3.0. Подключение модулей к основной программе осуществляется с помощью служебного слова uses: uses <имена модулей>; Имя модуля должно совпадать с имением дискового файла, содержащего исходный текст модуля. Таким образом, служебное слово uses устанавливает связь основной программы с этим файлом. Слово uses должно следовать сразу за заголовком программы. Режимы компиляции модулей (выбираются с помощью меню COMPILE). BUILD в этом режиме компилятор языка Turbo Pascal пытается отыскать и откомпилировать все файлы, которые имеют расширение .pas, и имена которых совпадают с именами модулей, объявленных в тексте программы с помощью служебного слова uses. Все изменения, сделанные программистом в тексте основной программы и в текстах модулей, будут учтены при компиляции в этом режиме. Результат компиляции каждого модуля помещается в файл с расширением .tpu (Turbo Pascal Unit).
5
MAKE
в этом режиме компилятор проверяет наличие всех файлов, которые имеют расширение .tpu, и имена которых совпадают с именами модулей, объявленных в тексте программы с помощью служебного слова uses. Если какой-либо из этих файлов не найден, компилятор пытается отыскать файл с тем же именем и с расширением .pas и откомпилировать его. Кроме того, компилятор проверяет, были ли внесены изменения в исходный текст модуля (файл с расширением .pas). Если были внесены изменения, файл с исходным текстом модуля (с расширением .pas) заново компилируется независимо от наличия уже откомпилированного файла (с расширением .tpu). Все модули, обращающиеся к этому измененному модулю, будут также перекомпилированы. Это гарантирует соответствие между модулями и основной программой при внесении изменений в текст одного из них. Если исходный текст модуля не найден, но существует откомпилированный файл (с расширением .tpu), компилятор использует этот файл. COMPILE в этом режиме все используемые в программе модули должны быть предварительно откомпилированы. Компилируется программа или модуль, который находится в текущем окне редактора Turbo Pascal. При компиляции и последующем запуске программы с помощью меню RUN/RUN компиляция проходит в режиме MAKE. Любой программный модуль имеет следующую структуру: unit <имя модуля>; {Заголовок} Interface <интерфейсная часть> Implementation <исполняемая часть> begin <инициирующая часть> end. Каждая из частей модуля (кроме заголовка) может отсутствовать. Заголовок состоит из служебного слова unit и имени модуля: unit <имя модуля>; В отличие от заголовка основной программы, который начинается со слова program и который можно опускать, заголовок модуля обязателен. Заголовок должен совпадать с именем дискового файла, в котором сохраняется текст мо-
6
дуля, опять-таки в отличие от заголовка основной программы, который может быть произвольным идентификатором. Это необходимо для установления правильной связи основной программы с модулем. Интерфейсная часть открывается служебным словом Interface Отметим, что модули, так же как и программы, могут использовать, в свою очередь, другие модули. Ссылка на другой модуль может содержаться либо в самом начале интерфейсной части, сразу же за словом Interface, либо в самом начале исполняемой части, сразу за словом Implementation. Допускается также подключение модулей и в начале интерфейсной, и в начале исполняемой части (в двух местах). Пусть, например, в нашем модуле используются процедуры стандартного модуля CRT. В таком случае сразу за словом Interface мы помещаем служебную фразу uses CRT; В языке Turbo Pascal запрещается прямое или косвенное обращение модуля к самому себе (например, когда модуль a вызывает модуль b, а модуль b, в свою очередь, снова вызывает модуль a). Исключение составляет косвенный (перекрестный) вызов модулей в исполняемой части. При этом интерфейсные части обоих модулей компилируются независимо. В интерфейсной части содержится объявление всех глобальных объектов модуля (типов данных, констант, переменных, процедур и функций). При необходимости любой из объектов, описанных в интерфейсной части модуля, можно переопределить в тексте основной программы. Переопределение объекта означает, что вновь объявленный в основной программе объект "закрывает" ранее определенный в модуле одноименный объект. Обратим внимание, что при объявлении процедур и функций в интерфейсной части помещаются только их заголовки; полное описание процедур и функций помещается в исполняемой части (после слова Implementation). Исполняемая часть открывается служебным словом Implementation и содержит описание процедур и функций, объявленных в интерфейсной части. В описании процедур и функций в исполняемой части модуля в заголовке процедуры или функции можно опускать список формальных параметров и тип результата функции, поскольку они уже были описаны в интерфейсной части. Если же в исполняемой части заголовок процедуры или функции повторяется в полном виде (включая список формальных параметров), он должен в точности совпадать с заголовком, объявленным в интерфейсной части. Инициирующая часть модуля ограничивается служебными словами begin .. end.
7
Инициирующая часть может отсутствовать, − в таком случае отсутствует служебное слово begin, и текст модуля завершается служебным словом end, сопровождаемом точкой (как и в конце любой программы). Инициирующая часть может содержать исполняемые операторы (некоторый фрагмент программы). Эти операторы выполняются до передачи управления основной программе и обычно используются для подготовки ее к работе. Например, инициирующая часть может открывать файлы, необходимые для работы основной программы. Пусть, например, инициирующая часть модуля вызывает процедуру очищения экрана ClrScr, содержащуюся в стандартном модуле CRT (выше мы подключили этот модуль с помощью служебного слова uses). begin ClrScr end. Теперь перед началом работы основной программы экран будет очищен. Рассмотрим небольшую программу, которая выполняет арифметические операции над комплексными числами. Введем специальный тип данных compl − запись, полями записи являются действительная и мнимая части комплексного числа. Напишем специальные процедуры сложения, вычитания, умножения и деления комплексных чисел. Описание типа compl и процедур выделим в специальный модуль complex, который находится в файле complex.pas. В нашем примере интерфейсная часть включает описание типа compl, а также заголовки процедур сложения AddC, вычитания SubC, умножения MulC и деления DivC комплексных чисел. Исполняемая часть включает описание процедур AddC, SubC, MulC и DivC. Ниже приводится текст модуля complex: Unit Complex; {Это модуль, включающий описание процедур, выполняющих арифметические операции над комплексными числами. Он имеет имя complex и сохранен в файле complex.pas} Interface {Интерфейсная часть} uses CRT; type compl = record re, im: real
8
end; Procedure Procedure Procedure Procedure
AddC SubC MulC DivC
(x, (x, (x, (x,
y: y: y: y:
compl; compl; compl; compl;
var var var var
z: z: z: z:
compl); compl); compl); compl);
{Конец интерфейсной части} Implementation {Исполняемая часть} Procedure AddC; begin {AddC} z.re := x.re + y.re; z.im := x.im + y.im end; {AddC} Procedure SubC; begin {SubC} z.re := x.re - y.re; z.im := x.im - y.im end; {SubC} Procedure MulC; begin {MulC} z.re := x.re * y.re - x.im * y.im; z.im := x.re * y.im + x.im * y.re end; {MulC} Procedure DivC; var modz: real; begin {DivC} modz := sqr(y.re) + sqr(y.im); z.re := (x.re * y.re + x.im * y.im) / modz; z.im := (x.im * y.re - x.re * y.im) / modz end; {DivC} {Конец исполняемой части}
9
{Инициирующая часть} begin {Очищение экрана перед исполнением программы} ClrScr end. {Конец инициирующей части} {Конец модуля complex} Текст основной программы, использующей модуль complex: Program Units; uses complex; var sign: char; a, b, c: compl; {Тип compl не нуждается в описании в основной программе} begin {Program} write('Программа выполняет '); write('арифметические операции '); writeln('над комплексными числами.'); write('Введите действительные '); write('и мнимые части '); writeln('двух комплексных чисел A и B.'); write('Re A: '); readln(a.re); write('Im A: '); readln(a.im); write('Re B: '); readln(b.re); write('Im B: '); readln(b.im); write('Введите знак арифметической '); write('операции (+, -, *, /): '); readln(sign); case sign of '+': AddC(a, b, c); '-': SubC(a, b, c); '*': MulC(a, b, c); '/': DivC(a, b, c)
10
end; {Описания процедур AddC, SubC, MulC и DivC содержатся в модуле complex} write('C = ', c.re:4:2, ' + '); writeln(c.im:4:2, ' i') end.
МОДУЛЬ CRT Процедуры и функции модуля CRT расширяют возможности текстового ввода и вывода на экран. Аббревиатура CRT раскрывается как cathode-ray tube − электронно-лучевая трубка и употребляется в значении "дисплей". Модуль присоединяется к основной программе с помощью стандартной фразы: Uses CRT; Функции модуля CRT: KeyPressed логическая функция типа boolean. Возвращает true, если на клавиатуре была нажата какая-либо клавиша, и false − в противном случае. Не задерживает выполнение программы. ReadKey функция типа char. Анализирует буфер клавиатуры: если в нем уже содержатся код считанного с клавиатуры символа, этот символ становится значением функции. В противном случае работа программы приостанавливается до нажатия какой-либо клавиши. При этом учитываются не только коды алфавитно-цифровых клавиш, но также и функциональных и управляющих клавиш (за исключением клавиш SHIFT, CTRL, ALT, CAPS LOCK, NUM LOCK, SCROLL LOCK, если они не нажаты в сочетании с другими клавишами, и F11, F12). WhereX функция типа byte. Ее значением является горизонтальная координата текущей позиции курсора относительно экрана или окна. WhereY функция типа byte. Ее значением является вертикальная координата текущей позиции курсора относительно экрана или окна.
11
Основные процедуры модуля CRT: TextMode (<режим>) устанавливает текстовой режим. TextColor (<цвет>) устанавливает цвет символов. TextBackground (<цвет>) устанавливает цвет фона. Window (<x1>, , <x2>, ) определяет текстовое окно. (<x1>, ) − координаты левого верхнего угла окна; (<x2>, ) − координаты правого нижнего угла окна, причем левый верхний угол экрана имеет координаты (1, 1). <x1>, , <x2>, должны иметь тип byte. Окно очищается (заполняется цветом фона), курсор помещается в левый верхний угол окна. Если нарушаются условия x1 < x2, y1 < y2 или какая-либо из координат выходит за границы экрана, процедура Window игнорируется. Обращение к процедуре Window отменяет предыдущее определение окна. ClrScr очищает экран или окно, при этом экран или окно заполняется цветом фона. Курсор устанавливается в левый верхний угол. GotoXY (<x1>, ) помещает курсор в позицию с координатами (<x1>, ) экрана или окна. <x1>, должны иметь тип byte. Если какая-либо из координат выходи за границы экрана (окна), процедура GotoXY игнорируется. ClrEOL стирает часть строки от текущего положения курсора до правой границы экрана или окна. Положение курсора не изменяется. DelLine уничтожает всю строку, в которой находится курсор, на экране или в окне. Все строки ниже удаляемой (если они есть) сдвигаются вверх на одну строку. InsLine вставляет строку выше строки, в которой находится курсор, на экране или в окне. Строка, в которой находится курсор, и все строки ниже ее (если они есть) сдвигаются вниз на одну строку. Строка, вышедшая за нижнюю границу экрана или окна, теряется. LowVideo устанавливает пониженную яркость символов.
12
NormVideo устанавливает нормальную яркость символов. HighVideo устанавливает повышенную яркость символов. В качестве параметра <цвет> в процедурах TextColor и TextBackground необходимо использовать выражение типа byte, задающее код цвета. Удобно использовать следующие константы, определенные в модуле CRT: Black = 0 черный; Blue = 1 темно-синий; Green = 2 темно-зеленый; Cyan = 3 бирюзовый; Red = 4 красный; Magenta = 5 фиолетовый; Brown = 6 коричневый; LightGray = 7 светло-серый; DarkGray = 8 темно-серый; LightBlue = 9 светло-синий; LightGreen = 10 светло-зеленый; LightCyan = 11 светло-бирюзовый; LightRed = 12 розовый; Lightmagenta = 13 малиновый; Yellow = 14 желтый; White = 15 белый; Blink = 128 мерцание символов. В качестве примера рассмотрим небольшую программу, которая выводит на экран таблицу значений функций f1, f2, f3, используя различные возможности оформления текста на экране. Program CRT_unit; var b, dx, x: real; i: byte; Function f1 (x1: real): real; begin {f1} f1 := sqr(x1); end; {f1} Function f2 (x1: real): real; begin {f2} f2 := sqr(x1) * x1; end; {f2}
13
Function f3 (x1: real): real; begin {f3} f3 := sqr(sqr(x1)); end; {f3} begin {Program} TextBackground(White); TextColor(Magenta); ClrScr; GotoXY(5, 2); write('Программа выводит на экран '); write('таблицу значений трех функций: '); write('F1, F2 и F3'); GotoXY(30, 3); write('на интервале [A, B]'); TextColor(Red); GotoXY(9, 5); write('Введите границы интервала: '); TextColor(LightRed); write('A = '); read(x); GotoXY(45, 5); write('B = '); read(b); TextColor(Red); GotoXY(9, 6); write('Введите шаг: '); TextColor(LightRed); write('DX = '); read(dx); TextColor(LightBlue); GotoXY(17, 9); write('x:'); GotoXY(32, 9); write('f1:'); GotoXY(48, 9); write('f2:'); GotoXY(64, 9); write('f3:'); TextColor(Green); GotoXY(9, 10);
14
for i := 1 to 64 do write('-'); TextColor(Blue); i := 1; while x <= b do begin GotoXY(11, 10 + i); write(x:12:6); GotoXY(27, 10 + i); write(f1(x):12:6); GotoXY(43, 10 + i); write(f2(x):12:6); GotoXY(59, 10 + i); write(f3(x):12:6); x := x + dx; i := i + 1 end end. {Program} МОДУЛЬ GRAPH Для работы с графикой в языке Turbo Pascal имеется специальная библиотека (модуль) GRAPH, которая содержит более 50 процедур и функций. Здесь мы рассмотрим некоторые из них, необходимые для построения графиков математических функций. Для того, чтобы познакомиться со всеми процедурами и функциями, рекомендуется обратиться к более полному руководству по языку Turbo Pascal. Переход в графический режим осуществляется с помощью процедуры InitGraph (<драйвер>, <режим>, <путь>); Здесь <драйвер> − переменная типа integer, задающая тип графического драйвера. В модуле GRAPH определены следующие константы, которые могут быть использованы в качестве значений этой переменной: Detect = 0; CGA = 1; MCGA = 2; EGA = 3; EGA64 = 4; EGAMono = 5; IBM8514 = 6; HercMono = 7; Att400 = 8;
15
VGA = 9; PC3270 = 10; Рекомендуется использовать в качестве значения переменной <драйвер> константу Detect, которая соответствует автоматическому определению типа драйвера. <режим> − переменная типа integer, с помощью которой можно задать режим графики (таких режимов несколько для каждого типа графического адаптера). При этом также можно использовать специальные константы, определенные в модуле GRAPH. Однако делать это не обязательно: при выборе автоматического определения, задаваемого константой Detect, режим будет установлен автоматически. <путь> − это выражение типа string, которое должно содержать путь к каталогу, в котором находится файл графического драйвера. Как правило, это один из подкаталогов каталога, в котором содержатся программные файлы языка Turbo Pascal (подкаталог \bgi). С помощью функции GraphResult (задается без параметров) можно проверить правильность перехода в графический режим. Значением является число типа integer. Если переход в графический режим осуществлен без ошибок, функция принимает значение 0, в противном случае - отрицательное число, в котором закодирована информация об ошибке. С помощью функции GraphErrorMsg можно вывести на экран сообщение, соответствующее коду ошибки. Единственным параметром функции является выражение типа integer, задающее код ошибки (как правило, это значение функции GraphResult). Значением функции является строка (тип string), содержащая сообщение об ошибке. Она может быть выведена на экран процедурой writeln. Процедура CloseGraph завершает работу в графическом режиме и восстанавливает текстовой режим. Нам потребуются также следующие процедуры модуля GRAPH: SetColor (<цвет>) устанавливает текущий цвет линий и символов. В модуле GRAPH определены такие же константы для задания цвета, как и в модуле CRT (см. раздел 16).
16
SetViewPort (<x1>, , <x2>, , <отсечка>) определяет окно вывода на графическом экране. (<x1>, ) − координаты левого верхнего угла окна; (<x2>, ) − координаты правого нижнего угла окна, причем левый верхний угол экрана имеет координаты (0, 0). <x1>, , <x2>, должны иметь тип integer. <отсечка> − параметр типа boolean, который определяет, будут ли игнорироваться те элементы изображения, чьи координаты лежат за пределами указанного окна, или они также будут выводиться на экран. В первом случае параметр должен иметь значение true, во втором − false. В модуле GRAPH определены следующие константы для задания этого параметра: ClipOn = true (включить отсечку элементов изображения); ClipOff = false (не включать отсечку элементов изображения). Rectangle (<x1>, , <x2>, ) вычерчивает прямоугольник. (<x1>, ) − координаты левого верхнего угла прямоугольника относительно окна (экрана); (<x2>, ) − координаты правого нижнего угла прямоугольника относительно окна (экрана). Левый верхний угол окна (экрана) имеет координаты (0, 0). <x1>, , <x2>, должны иметь тип integer. Bar (<x1>, , <x2>, ) заполняет прямоугольную область. (<x1>, ) − координаты левого верхнего угла области относительно окна (экрана); (<x2>, ) - координаты правого нижнего угла области относительно окна (экрана). Левый верхний угол окна (экрана) имеет координаты (0, 0). <x1>, , <x2>, должны иметь тип integer. Если не установлены стиль и цвет с помощью процедуры SetFillStyle, процедура заполняет указанную область текущим цветом и сплошным заполнением. Line (<x1>, , <x2>, ) вычерчивает линию. (<x1>, ) − координаты начала линии относительно окна (экрана); (<x2>, ) − координаты конца линии относительно окна (экрана). Левый верхний угол окна (экрана) имеет координаты (0, 0). <x1>, , <x2>, должны иметь тип integer. Если не установлены стиль и цвет с помощью процедуры SetLineStyle, процедура чертит сплошную линию текущим цветом.
17
PutPixel (<x>, , <цвет>) выводит точку указанного цвета. (<x>, ) − координаты точки относительно окна (экрана). Левый верхний угол окна (экрана) имеет координаты (0, 0). <x>, должны иметь тип integer; параметр <цвет> должен иметь тип word. OutTextXY (<x>, , <строка>) выводит строку символов, начиная с указанной точки. (<x>, ) − координаты начала строки относительно окна (экрана). Левый верхний угол окна (экрана) имеет координаты (0, 0). <x>, должны иметь тип integer; параметр <строка> должен иметь тип string. MoveTo (<x>, ) помещает графический курсор в точку с координатами (<x>, ) относительно окна (экрана). Левый верхний угол окна (экрана) имеет координаты (0, 0). <x>, должны иметь тип integer. LineTo (<x>, ) вычерчивает линию от текущего положения графического курсора до точки с координатами (<x>, ) относительно окна (экрана). Левый верхний угол окна (экрана) имеет координаты (0, 0). <x>, должны иметь тип integer. Если не установлены стиль и цвет с помощью процедуры SetLineStyle, процедура чертит сплошную линию текущим цветом. Ниже мы рассмотрим программу, которая строит график заданной функции f(x) на заданном отрезке. В предлагаемой реализации программы построения графика вывод осуществляется в область экрана, выделяемую процедурой SetViewPort модуля GRAPH. Нужно помнить, что разрешение экрана в графическом режиме − 640 × 480 точек, нумеруемых от 0 до 639 в горизонтальном направлении и от 0 до 479 в вертикальном направлении (см. рис. 1). В процедуре Screen экран подготавливается к выводу графика. Вычерчивается рамка синего цвета (цвет устанавливается процедурой SetColor). Рамка ограничивает область вывода, она составлена из пяти прямоугольников
18
(процедура Rectangle модуля GRAPH), так что ширина рамки − пять точек. С помощью процедуры SetViewPort определяется окно вывода размером 600 × 400 точек. Окно вывода заполняется белым цветом с помощью процедуры Bar, после чего в качестве текущего цвета вновь выбирается синий. Процедура CoordinatesRange позволяет ввести с клавиатуры отрезок [a..b], на котором будет построен график функции, и определить область значений [ymin..ymax] заданной функции на этом интервале, а также шаги dx, dy, которые соответствуют переходу от точки к точке графического экрана по осям X, Y. С учетом того, что в окне вывода необходимо разместить координатные оси, область, которую реально займет график функции, будет меньше окна вывода, определяемом процедурой SetViewPort, и составит 400 × 300 точек (рис. 3). Процедура Axes выводит на экран координатные оси. В зависимости от того, в какой части плоскости расположен график функции, возможны различные варианты вывода на экран координатных осей. Так, если график расположен в правой полуплоскости (a > 0), вертикальная ось выводится слева от графика; если график расположен в левой полуплоскости (b < 0), вертикальная ось выводиться справа; если график расположен в обеих полуплоскостях (a < 0 и b > 0), вертикальная ось проходит через точку 0 отрезка [a..b]. Аналогично, если график расположен в верхней полуплоскости (ymin > 0), горизонтальная ось выводится снизу от графика; если график расположен в нижней полуплоскости (ymax < 0), горизонтальная ось выводиться сверху; если график расположен в обеих полуплоскостях (ymin < 0 и ymax > 0), вертикальная ось проходит через точку 0 отрезка [ymin..ymax] (см. рис. 3 A − C). На рис. 4 поясняется расположение вертикальной и горизонтальной осей координат. Построение на экране собственно графика функции осуществляется процедурой Graphics. Для каждой точки (x, y), где y = f(x), вычисляются координаты (xi, yi) относительно окна вывода. Графический курсор помещается в начальную точку графика функции (процедура MoveTo). Затем в цикле вычисляются координаты последующих точек графика, которые соединяются между собой небольшими отрезками с помощью процедуры LineTo. Program Graph_unit; uses Graph; var Driver, Mode: integer; a, b, ymin, ymax, dx, dy: real;
19
Function f(x: real): real; {Определение функции f(x)} begin f := sqr(x) * exp( - abs(x)) end; Procedure Screen; {Процедура выделения область экрана для построения графика} var i: integer; begin {Screen} {Черчение рамки} SetColor(Blue); for i := 1 to 5 do Rectangle(14 + i, 34 + i, 625 - i, 445 - i); {Определение окна для вывода графика функции и заполнение его белым цветом. Затем в качестве текущего снова устанавливается синий цвет.} SetViewPort(20, 40, 619, 439, ClipOff); SetColor(White); Bar(0, 0, 599, 399); SetColor(Blue); end; {Screen} Procedure CoordinatesRange(var a, b, ymin, ymax, dx, dy: real); {Определение отрезка [a..b], области значений функции [ymin..ymax] и шагов dx, dy по осям координат} var x, y: real; begin {CoordinatesRange} write(' График функции F(x)'); write(' '); write('Введите интервал: A = '); readln(a); write(' '); write(' ');
20
write(' B = '); readln(b); {Начало отрезка должно определяться значением переменной a} x := a; if b < a then begin a := b; b := x; x := a end; {График функции будет занимать 400 точек по оси X. dx - шаг перехода от точки к точке по оси X} dx := (b - a) / 400; {Определение максимума и минимума функции на заданном интервале} ymax := f(a); ymin := ymax; while x <= b do begin y := f(x); if y > ymax then ymax := y; if y < ymin then ymin := y; x := x + dx end; {График функции будет занимать 300 точек по оси Y. dy - шаг перехода от точки к точке по оси Y} dy := (ymax - ymin) / 300 end; {CoordinatesRange} Procedure Axes(a, b, ymin, ymax, dx, dy: real); {Процедура вычерчивания осей координат} var stra, strb, strymin, strymax: string; ax, ay, axp, ayp: integer; axm, aym, axmm, aymm: integer; begin {Axes} {Определение положения вертикальной оси}
21
if a >= 0 then ax := 60; if b <= 0 then ax := 520; if (a < 0) and (b > 0) then ax := 90 + round(abs(a) / dx); axp := ax + 3; axm := ax - 3; if a >= 0 then axmm := ax - 50 else axmm := ax + 5; {Вычерчивание вертикальной оси, стрелки, насечек, соответствующих максимальному и минимальному значениям функции} Line(ax, 10, ax, 390); Line(ax, 10, axm, 20); Line(ax, 10, axp, 20); Line(axm, 50, axp, 50); Line(axm, 350, axp, 350); {Преобразование вещественных значений максимального и минимального значений функции ymin, ymax в строки символов strymin, strymax, и вывод этих значений на экран} str(ymax:5:2, strymax); str(ymin:5:2, strymin); OutTextXY(axmm, 48, strymax); OutTextXY(axmm, 348, strymin); {Определение положения горизонтальной оси} if ymin >= 0 then ay := 360; if ymax <= 0 then ay := 40; if (ymin < 0) and (ymax > 0) then ay := 350 - round(abs(ymin) / dy); ayp := ay + 3; aym := ay - 3; if ymin >= 0 then aymm := ay + 8 else aymm := ay - 12; {Вычерчивание горизонтальной оси, стрелки, насечек, соответствующих
22
началу и концу отрезка} Line(10, ay, 590, ay); Line(580, ayp, 590, ay); Line(580, aym, 590, ay); Line(90, aym, 90, ayp); Line(490, aym, 490, ayp); {Преобразование вещественных значений начала и конца отрезка [a..b] в строки символов stra, strb, и вывод этих значений на экран} str(a:5:2, stra); str(b:5:2, strb); OutTextXY(70, aymm, stra); OutTextXY(470, aymm, strb); end; {Axes} Procedure Graphics(a, dx, dy: real); {Процедура вывода графика функции} var x, y: real; xi, yi: integer; begin {Graphics} SetColor(Red); x := a; yi := 350 - round((f(a) - ymin) / dy); MoveTo(90, yi); for xi := 90 to 490 do begin x := x + dx; y := f(x); yi := 350 - round((y - ymin)/dy); LineTo(xi, yi) end end; {Graphics} begin {Program} {Переход в графический режим} Driver := Detect; InitGraph(Driver, Mode, 'c:\bp\bgi\'); {Проверка правильности перехода в графический режим} if GraphResult <> 0
23
then writeln(GraphErrorMsg(GraphResult)) else begin Screen; CoordinatesRange(a, b, ymin, ymax, dx, dy); Axes(a, b, ymin, ymax, dx, dy); Graphics(a, dx, dy); SetColor(White); OutTextXY(0, 420, 'Нажмите ENTER...'); readln; CloseGraph; end end. {Program}
24
480
Рис. 1. Разрешение экрана в графическом режиме.
640
(639, 479)
Рис. 2. Определение области вывода. (20, 40)
400
(0, 0)
(619, 439) 600
25
Различные варианты вывода координатных осей на экран. Рис. 3-A.
5
Область вывода 300
графика функции
2 1
7
400
Рис. 3-B.
-7
-1 -2
Область вывода графика функции
-5
26
Рис. 3-C.
3 Область вывода графика функции -3
4
-2
Рис. 4. Расположение вертикальной и горизонтальной осей на экране. (ax, 10) (axm, 20)
(axp, 20)
(axm, 50)
(axp, 50)
(90, aym) (10, ay)
(590, ay) (90, ayp)
ayp = ay + 3 aym = ay − 3
(axm, 350)
(axp, 350)
(ax, 390) axp = ax + 3 axm = ax − 3
(490, aym) (580, aym)
(490, ayp) (580, ayp)
27
ЛИТЕРАТУРА 1. В. Э. Фигурнов, IBM PC для пользователя. Краткий курс, М., 1999. 2. В. В. Фаронов, Turbo Pascal 7.0. Начальный курс, М., Изд-во "Нолидж", 1998. 3. Л. А. Бугаев, Г. М. Чечин, К. Н. Жучков, Методические указания к проведению практических занятий по курсу "Информатика". Вып. 1.1. Необходимые определения и команды для работы на компьютере. Элементы языка Pascal (часть I), Ростов-на-Дону, УПЛ РГУ, 1998. 4. Л. А. Бугаев, Г. М. Чечин, К. Н. Жучков, Методические указания к проведению практических занятий по курсу "Информатика". Вып. 1.4.Задачи для самостоятельного решения на компьютере, Ростов-на-Дону, УПЛ РГУ, 1998. 5. Шестакова Т. П. Методические указания по курсу "Программирование и вычислительная физика". Часть I. Основные конструкции языка Turbo Pascal. Простейшие типы данных, Ростов-на-Дону, УПЛ РГУ, 2003. 6. Шестакова Т. П. Методические указания по курсу "Программирование и вычислительная физика". Часть II. Процедуры и функции в языке Turbo Pascal. Перечисляемые типы данных, тип-диапазон и оператор case. Массивы, Ростов-на-Дону, УПЛ РГУ, 2003. 7. Шестакова Т. П. Методические указания по курсу "Программирование и вычислительная физика". Часть III. Типы данных языка Turbo Pascal. Файлы. Записи, Ростов-на-Дону, УПЛ РГУ, 2003. 8. Шестакова Т. П. Методические указания по курсу "Программирование и вычислительная физика". Часть IV. Типы данных языка Turbo Pascal. Указатели. Строки. Множества, Ростов-на-Дону, УПЛ РГУ, 2003.