Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Решение математических задач.pdf
Скачиваний:
28
Добавлен:
13.02.2015
Размер:
858.1 Кб
Скачать

Рис. 4.3. Результаты работы программы построения круговой диаграммы, отражающей успеваемости группы студентов по итогам сессии

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

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

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

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

97

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

и240 по вертикали.

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

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

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

следующий:

putpixel(x,y,цвет);

где putpixel служебное слово, означающее в переводе «поставить

точку»;

x и y – координаты изображаемой на экране точки;

цвет – один из стандартных цветов палитры языка Паскаль, в

который будет окрашена данная точка.

Для того чтобы наглядно проиллюстрировать вышеприведенные

положения, рассмотрим процесс построения графика функции натурального логарифма y=ln(x). Приведем сперва текст программы grafikln,

производящей построение графика, а затем подробно его прокомментируем.

program grafikln; Uses Crt,Graph;

const

mtx=50; mty=50; xn=80; yn=240;

var grad,grreg,i,m,n,g,v:integer; x,y,x0,y0:real;

begins:string; grad:= detect;

InitGraph(grad,grreg,'d:\tp7\bgi');

SetbkColor(LightGray);

ClearDevice;

SetColor(Blue);

line(10,yn,630,yn);

line(xn,10,xn,470);

OuttextXY(65,10,'Y');

OuttextXY(620,250,'X');

98

OuttextXY(65,250,'0');

m:=trunc(540/mtx);

n:=trunc(460/mty); for i:=1 to m do

begin g:=i*mtx;

line(xn+g,yn-3,xn+g,yn+3); str(i,s); OuttextXY(xn+g-5,yn+10,s) end;

for i:=1 to n div 2 do begin

v:=i*mty; line(xn-3,yn-v,xn+3,yn-v); str(i,s); OuttextXY(xn-10,yn-v,s); line(xn-3,yn+v,xn+3,yn+v); str(-i,s); OuttextXY(xn-20,yn+v,s) end;

SettextStyle(defaultfont,horizdir,2);

Setcolor(green);

OuttextXY(120,20,'График функции y=ln(x)'); x0:=1;

repeatx:=x0/mtx; y:=ln(x); y0:=y*mty;

PutPixel(xn+trunc(x0),yn-trunc(y0),red); x0:=x0+0.01

until x0>540; readln; CloseGraph

end.

Начнем с определения положения начала декартовых координат. Так как функция натурального логарифма может иметь как положительные, так и отрицательные значения, то ноль по оси ординат целесообразно расположить посредине экрана, то есть точка начала отсчета должна иметь вертикальную графическую координату yn равную 240. Из математики

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

99

графическую координату начальной точки отсчета xn примем равной 80. Эти

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

В том же подразделе опишем еще две постоянные величины – это масштаб по оси абсцисс mtx и масштаб по оси ординат mty. Обе эти

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

В основной части программы после инициализации графического режима зададим цвет фона изображения – светло-серый. Так как при

построении графика мы не будем использовать черный цвет, то экран можно не заливать командой floodfill, а использовать процедуру cleardevice.

Затем изображаем ось абсцисс и ось ординат. Вначале командой setcolor задаем цвет изображения – синий. Затем рисуем сами оси с

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

горизонтальную графическую координату 10 – вблизи левого края экрана, а конечную координату 630 – вблизи правого края экрана. Вертикальная координата для всей оси абсцисс yn была нами определена ранее и равна

240. Аналогично для построения оси ординат берем начальную вертикальную координату 10 – вблизи верхнего края экрана, а конечную 470

– вблизи нижнего края. Горизонтальная графическая координата оси ординат xn также была задана заранее. Затем с помощью процедуры OuttextXY

рядом с концами осей пишем их обозначения, а около начала декартовых координат ставим цифру «0».

На следующем этапе рисуем деления на оси абсцисс и ординат. Условимся, что деления будут идти с шагом 1. Для того чтобы это сделать, нужно предварительно подсчитать количество требуемых делений. Начнем с подсчета необходимого числа делений по оси абсцисс. Для этого, прежде всего, нужно установить величину горизонтального графического диапазона, в котором будет строиться график. Начальное значение данного диапазона возьмем равным 80 (горизонтальная координата точки начала отсчета), а конечное значение примем равным 620, то есть вблизи правой границы экрана. Таким образом, величина горизонтального диапазона будет равна 540 (620-80). Полученную величину диапазона разделим на масштабный коэффициент mtx. Посредством стандартной функции trunc выделяем

целую часть полученного частного. Это и будет m - искомое количество

делений по оси абсцисс.

Для подсчета n — числа делений по оси ординат — прибегнем к

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

100

логарифмической функции являются как положительные, так и отрицательные значения, то диапазон по вертикали должен охватывать большую часть экрана. Поэтому в качестве начала данного диапазона возьмем точку с вертикальной координатой 10, а конца — 470. Таким образом, вертикальный диапазон составит в общей сложности 460 пикселей (470-10).

Вывод на экран делений и соответствующих им числовых обозначений организуем в цикле. Переменная цикла для оси абсцисс будет изменяться от 1 до m. В ходе работы цикла для каждого деления вычисляется его

расстояние от начала декартовых координат по горизонтали g, которое равно

произведению порядкового номера деления на масштабный коэффициент. Порядковый номер данного деления будет равен i – текущему значению

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

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

величина g. Начало данной черты по вертикали будет на 3 пикселя выше оси

абсцисс, то есть соответствующая вертикальная графическая координата будет равна yn-3. Горизонтальная координата нижней точки будет такой же,

что и для верхней, а по вертикали конец черты будет располагаться на 3 пикселя ниже, чем ось абсцисс, то есть вертикальная графическая координата будет равна yn+3. Теперь проводим черту оператором line.

Затем i — порядковый номер данного деления — необходимо преобразовать в строковую переменную s c помощью стандартной функции

str. Это необходимо сделать для того, чтобы можно было вывести этот порядковый номер под чертой с помощью оператора OuttextXY, так как

данный оператор позволяет выводить только строковые переменные или строковые константы (строки текста). Число, обозначающее какое-либо деление должно выводиться немного левее и ниже самого этого деления. Поэтому начальную точку вывода этого числа разместим на 10 пикселей ниже оси абсцисс (вертикальная координата – y0+10) и на 5 пикселей левее

самой черты (горизонтальная координата – x0+g-5).

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

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

представлять собой искомую величину n. Теперь разделим найденное число n пополам. Целая часть от n/2 даст нам количество делений, которое будет располагаться на каждой из половинок оси, как на положительной, так и на

101

преобразуется в

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

При каждом выполнении цикла будут производиться следующие операции: вначале вычисляется величина v – выраженное в пикселях

расстояние по вертикали от начала декартовых координат до очередного деления на оси ординат. Это расстояние будет равно произведению текущего значения переменной цикла i на масштабный коэффициент mty. Затем

определяются координаты начала и конца черты деления, расположенного на положительной половине оси ординат. Вертикальная графическая координата для всей этой черты будет единой – эта графическая координата точки начала отсчета yn за вычетом уже известной нам величины v . То

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

Затем определяем горизонтальные графические координаты начала и конца данной черты деления. Начало черты будет расположено на три пикселя левее точки начала отсчета xn, то есть будет равно xn-3. Конец

черты будет расположен на три пикселя правее этой же точки и будет равен xn+3. Теперь осталось провести линию командой line и вывести на экран

рядом с чертой деления число, обозначающее данное деление, для чего используется команда OuttextXY, причем, как и в случае с делениями на

оси абсцисс, в начале целочисленная переменная i

строковую переменную s, значение которой и выводится посредством OuttextXY. Переменная s выводится на том же вертикальном уровне, что

и черта деления, но на 10 пикселей левее оси ординат.

Далее в цикле наносится деление на отрицательной половине оси ординат. Это деление расположено по отношению к ранее нанесенному делению на положительной половине оси симметрично относительно начала точки отсчета. Вертикальная графическая координата этого деления будет равна координате начальной точки отсчета yn плюс величина v, так как она

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

отрицательная величина –i, и само число сдвигается еще на 10 пикселей

левее оси ординат, чтобы оставалось место для знака «минус».

После того как в результате работы цикла на оси нанесены все

необходимые деления, остается вывести в верхней части экрана заголовок графика. Для этого процедурой settextstyle задается более крупный

102

размер шрифта для заголовка, а затем процедурой outtextXY выводится

сам заголовок: «График функции y=ln(x)». Теперь, когда созданы оси с делениями и все необходимые надписи, можно непосредственно переходить к построению линии графика.

Для построения линии графика используем цикл с постусловием repeat..until. Линия графика строится по точкам и для ее построения

используется следующий принцип: берется некоторая точка, расположенная от точки начала отсчета по горизонтали на расстоянии x0. Для этой точки

определяется соответствующая ей декартова координата x, которая равна

величине аргумента функции в данной точке графика. Эта величина определяется путем деления значения x0 на масштабный коэффициент mtx.

Затем для аргумента x по формуле определяется соответствующее ему значение функции y. Затем вычисленное значение функции переводится в y0

— расстояние по вертикали от начала точки отсчета. Теперь не составит труда нанести на график точку с декартовыми координатами x и y.

Расстояние данной точки от точки начала отсчета по горизонтали и по вертикали в пикселях составит соответственно trunc(x0) и trunc(y0),

так как эти величины должны выражаться целым числом пикселей. Тогда

горизонтальная и вертикальная графические координаты данной точки будут равны соответственно xn+trunc(x0) и yn-trunc(y0). Во втором

случае мы опять сталкиваемся с ситуацией, когда расстояние не прибавляется к начальному значению, а вычитается из него, что связано с особенностями графической системы координат. Данные координаты и будут параметрами процедуры Putpixel. Последний параметр процедуры – цвет

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

Начальное значение переменной x0 возьмем равным 1, то есть строить

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

случае соответствующее значение y становится равным бесконечности, а

подсчитать, чему равна бесконечность, компьютер естественно не может, о чем он и оповещает пользователя, выдавая сообщение об ошибке. В дальнейшем x0 принимает значения вплоть до 540, то есть проходит по

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

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

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

103

Рис. 4.4. Результат работы программы, которая строит график логарифмической функции

Это противоречие, однако, объясняется достаточно просто. Дело в том, что если бы мы увеличивали x0 c шагом, равным единице, то график бы

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

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

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

По достижении переменной x0 значения 540, что соответствует

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

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

104