Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Рекомендации по выполнению задания




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

{ ПАРАМЕТРЫ РИСУНКА МОЖНО ИЗМЕНИТЬ В МОДУЛЕ Consts }

uses

Crt,

Graph, { модуль графической библиотеки }

Consts, { модуль с константами }

Types, { модуль описания типов данных }

Mathem1, { модуль математических преобразований }

Draw1, { модуль процедур и функций для рисования }

{ МОДУЛИ ДЛЯ САМОСТОЯТЕЛЬНОЙ РАБОТЫ }

Mathem2, { модуль математических преобразований }

Draw2; { модуль процедур и функций для рисования }

{ Первая математическая функция }

function F1(x:real):real; far; { Дальняя ссылка }

begin

F1:=9*x*x-11;

end;

{ Вторая математическая функция }

function F2(x:real):real; far; { Дальняя ссылка }

begin

F2:=x*x*x+5;

end;

{ **************** Основная часть **************** }

var

M1,M2:TMatMas; { Таблицы математических функций }

Y1min,Y2min, { Минимумы и... }

Y1max,Y2max, {... максимумы математических функций }

Ymin,Ymax:real; { Абсолютный минимум и максимум функций }

Kx,Ky:real; { Масштабирующие коэффициенты }

Ms1,Ms2:TScrMas; { "Экранные" таблицы }

Xo,Yo:word; { Координаты "экранного" нуля }

RootMas:TRoot; { Массив точек пересечения }

K:word; { Количество точек пересечения }

Rect:TRect; { Прямоугольник для вывода графика }

begin

{ ********* Подготовка данных для рисования *********** }

with Rect do

begin

Origin.X:=OriginX;

Origin.Y:=OriginY;

Size.X:=Nx;

Size.Y:=Ny;

end;

{ Заполнение таблиц математических функций }

EnterMatMas (M1,Nx,@F1,Xmin,Xmax);

EnterMatMas (M2,Nx,@F2,Xmin,Xmax);

{ Вычисление минимума и максимума математических функций }

Y1min:=Min(M1,Nx); Y1max:=Max(M1,Nx);

Y2min:=Min(M2,Nx); Y2max:=Max(M2,Nx);

Ymin:=Minimum(Y1min,Y2min);

Ymax:=Maximum(Y1max,Y2max);

{ Вычисление масштабирующих коэффициентов }

Kx:=Nx/(Xmax-Xmin);

Ky:=Ny/(Ymax-Ymin);

{ Заполнение "экранных" таблиц }

EnterScrMas(Ms1,M1,Ymin,Ky,Rect);

EnterScrMas(Ms2,M2,Ymin,Ky,Rect);

{ Вычислить координаты "экранного" нуля }

Zero(Xmin,Xmax,Ymin,Ymax,Rect,Kx,Ky,Xo,Yo);

{ Найти точки пересечения }

K:=Solution(Xmin,Xmax,@F1,@F2,RootMas);

{ ********************** Рисование ********************* }

GraphInit;

{ Нарисовать рамку }

Ramka(Rect,Width,Cyan);

{ Рисование граничных значений по углам рамки }

DrawBounds(Xmin,Xmax,Ymin,Ymax,Rect,Red);

{ Рисование координатной сетки }

DrawGridLines(NgrX,NgrY,Rect,DarkGray);

{ Нарисовать оси }

DrawAxis(Rect,Xo,Yo,Red);

{ Нарисовать функции }

DrawFunction(Ms1,Nx,LightGreen);

DrawFunction(Ms2,Nx,Yellow);

{ Вывести координаты точек пересечения }

WriteCoord(RootMas,K,Rect,LightGreen);

ReadKey;

CloseGraph;

end.

Разбиение текста программы на отдельные модули позволяет сделать программу более «читабельной». Пусть даже эти модули очень небольшие.

unit Consts;

interface

const

Nx=440; { Размер графика по оси X }

Ny=480; { Размер графика оси Y }

OriginX=180; OriginY=40; { Левый верхний угол рамки }

Xmin=-2; Xmax=2; { Начальное и конечное значения аргумента }

NgrX=6; NgrY=23; { Количество линий координатной сетки }

Epsilon=0.001; { Точность решения }

R=10; { Количество поддиапазонов }

const

Width=3; { Ширина рамки }

implementation

end.

Модуль используемых типов.

unit Types;

interface

uses Consts;

type

TMatMas=array[1..Nx] of real; { Тип математической таблицы }

TScrMas=array[1..Nx] of word; { Тип "экранной" таблицы }

TRealCoord=record x,y:real; end; { Тип координата в действит. числах }

TRoot=array[1..Nx div 10] of TRealCoord; { Тип массив точек пересечения }

TIntCoord=record x,y:word; end; { Тип координата в целых числах }

TRect=record { Координаты прямоугольника }

Origin:TIntCoord; { Левый верхний угол }

Size:TIntCoord; { Размер }

end;

implementation

end.

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

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

unit Mathem1;

interface

uses Types, Consts;

procedure EnterMatMas (

var M: array of real; { Таблица математической функции }

Nx: word; { Количество точек в таблице }

Func: Pointer; { Указатель на математическую функцию }

Xmin,Xmax: real { Начальное и конечное значения аргумента }

);

{ Вычисление точек пересечения }

function Solution(

Xmin,Xmax:real; { Минимум и максимум аргумента }

F1,F2:pointer; { Математические функции }

var RootMas:TRoot): { Массив координат пересечения }

byte; { Количество точек пересечения }

implementation

procedure EnterMatMas(

var M: array of real; { Таблица математической функции }

Nx: word; { Количество точек в таблице }

Func: Pointer; { Указатель на математическую функцию }

Xmin,Xmax: real { Начальное и конечное значения аргумента }

);

type

TFunc = function (x:real):real; { Описание типа функции }

var

F: TFunc; { Математическая функция }

x: real; { Значение аргумента }

dx: real; { Шаг вычисления функции }

i: word; { Счетчик вычисляемых точек }

begin

F:=TFunc(Func); { Сделать ссылку на математическую функцию }

dx:=(Xmax-Xmin)/(Nx-1); { Вычислить шаг вычисления функции }

x:=Xmin; { Начальное значение аргумента }

for i:=0 to Nx-1 do { Цикл заполнения таблицы }

begin

M[i]:=F(x); { занести значение в массив }

x:=x+dx; { следующее значение аргумента }

end;

end;

{ Вычисление точек пересечения }

function Solution(

Xmin,Xmax:real; { Минимум и максимум аргумента }

F1,F2:pointer; { Математические функции }

var RootMas:TRoot): { Массив координат пересечения }

byte; { Количество точек пересечения }

type

TFunc = function (x:real):real; { Описание типа функции }

var

Fu1,Fu2: TFunc; { Математические функции }

{ Для вычисления точек пересечения задана новая функция,

как разность двух исходных }

function Fu(x:real):real;

begin

Fu:=Fu1(x)-Fu2(x);

end;

{ Определить, есть ли решения в поддиапазоне }

function SubRange (var FirstX, LastX, Step: real): boolean;

begin

{ Найти поддиапазон, на котором есть решение.

Из условия, что при прохождении через ось X функция меняет знак }

while (Fu(FirstX)*Fu(FirstX+Step)>0)and((FirstX+Step)<=Xmax) do

FirstX:= FirstX+Step;

if ((FirstX+Step)<=Xmax)

then

begin

LastX:= FirstX+Step;

SubRange:= True;

end

else SubRange:= False;

end;

{ Вычисление корня }

function Root (FirstX, LastX, NewStep: real): real;

begin

repeat

{ Вычислить новое значение шага }

NewStep:= NewStep/R;

{ Найти новый (уточненный) поддиапазон }

SubRange (FirstX,LastX,NewStep);

{ Определение правой границы поддиапазона }

LastX:= FirstX + NewStep;

until abs(NewStep)<=Epsilon/R; { Условие достижения заданной точности }

Root:= FirstX; { Возвращение корня }

end;

var

Step: real; { Величина подиапазона }

CurLeft,CurRight:real; { Границы отрезка, на котором есть решение }

k:word; { Номер точки пересечения }

begin

k:=0;

{ Задать функции }

Fu1:=TFunc(F1); Fu2:=TFunc(F2);

{ Вычислить начальный размер поддиапазона }

Step:=(Xmax-Xmin)/R;

{ Поиск решения с левой крайней границы отрезка }

CurLeft:= Xmin;

{ Цикл поиска всех решений }

while SubRange(CurLeft,CurRight,Step) do

begin

inc(k);

RootMas[k].X:=Root(CurLeft,CurRight,Step);

RootMas[k].Y:=Fu1(RootMas[k].X);

CurLeft:= CurRight;

end;

Solution:=K;

end;

end.

Задание: самостоятельно реализуйте реализацию (implementation) модуля Mathem2. Интерфейсная часть данного модуля имеет вид:

unit Mathem2;

interface

{ Функция вычисления минимума в массиве (таблице) точек }

function Min(

M: array of real; { Таблица математической функции }

N: word { Количество точек в таблице }

):real;

{ Функция вычисления минимума в массиве (таблице) точек }

function Max(

M: array of real; { Таблица математической функции }

N: word { Количество точек в таблице }

):real;

{ Выбор минимального из двух значений }

function Minimum(x,y:real):real;

{ Выбор максимального из двух значений }

function Maximum(x,y:real):real;

{ Процедура заполнения "экранной" таблицы }

procedure EnterScrMas(

var Ms: array of word; { "Экранная" таблица }

Mm: array of real; { Таблица математической функции }

Ymin: real; { Минимум математической функции }

K: real; { Коэффициент масштабирования }

var Rect { Прямоугольник вывода }

);

{ Вычислить координаты "экранного" нуля }

procedure Zero (

Xmin,Xmax,Ymin,Ymax:real; { Математические пределы изменения функций }

var Rect; { "Экранные" пределы изменения функций }

Kx,Ky:real; { Коэффициенты масштабирования }

var Xo,Yo:word); { Координаты "экранного" нуля }

implementation

end.

 

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

{*********** Процедуры и функции для работы с графикой *************}

unit Draw1;

interface

uses Types;

{ Инициализация графики }

procedure GraphInit;

{ Рисование функции по точкам из массива }

procedure DrawFunction(M:array of word;N:word;Color:byte);

{ Рисование рамки }

procedure Ramka(Rect:TRect;Width,Color:word);

implementation

uses Graph,Consts;

{ Инициализация графики }

procedure GraphInit;

var

Driver,Mode:integer;

Res:integer;

begin

Driver:=Detect;

InitGraph(Driver,Mode,'');

Res:=GraphResult;

if Res<>0 then

begin

WriteLn(GraphErrorMsg(Res));

WriteLn('Press <Enter> for exit');

ReadLn;

Halt(1);

end;

end;

{ Рисование функции по точкам из массива }

procedure DrawFunction(M:array of word;N:word;Color:byte);

var

i:word;

begin

SetColor(Color);

MoveTo(OriginX,M[0]);

for i:=1 to N-1 do

begin

LineTo(OriginX+i,M[i]);

{ PutPixel(OriginX+i,M[i],Color);}

end;

end;

{ Рисование рамки }

procedure Ramka(Rect:TRect;Width,Color:word);

var

i,OldColor:byte;

begin

OldColor:=GetColor;

SetColor(Color);

with Rect do

for i:=1 to Width do

Rectangle(Origin.X-i, Origin.Y-i,

Origin.X+Size.X+i, Origin.Y+Size.Y+i);

SetColor(OldColor);

end;

end.

Задание: самостоятельно реализуйте реализацию (implementation) модуля Draw2. Интерфейсная часть данного модуля имеет вид:

{*********** Процедуры и функции для работы с графикой *************}

unit Draw2;

interface

{ Нарисовать оси }

procedure DrawAxis(var Rect;Xo,Yo,Color:word);

{ Рисование граничных значений по углам рамки }

procedure DrawBounds(Xmin,Xmax,Ymin,Ymax:real;var Rect;Color:word);

{ Рисование координатной сетки }

procedure DrawGridLines(NgrX,NgrY:word;var Rect;Color:word);

{ Вывод координат точек пересечения }

procedure WriteCoord(var RootMas;K:word;var Rect;Color:word);

implementation

end.

 

Контрольные вопросы по теме № 8

1. Библиотечные функции графической библиотеки в языке Turbo Pascal.

2. Масштабирование функции для вывода в виде графика.

3. Тип процедура и тип функция. Преобразование типов.

4. Решение нелинейного алгебраического уравнения (метод деления отрезка пополам, метод простых итераций, метод пошаговых приближений).





Поделиться с друзьями:


Дата добавления: 2016-12-06; Мы поможем в написании ваших работ!; просмотров: 290 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Бутерброд по-студенчески - кусок черного хлеба, а на него кусок белого. © Неизвестно
==> читать все изречения...

2414 - | 2335 -


© 2015-2024 lektsii.org - Контакты - Последнее добавление

Ген: 0.012 с.