Программа вычисления значения и вывода графика определенного интеграла
p align="left">PROCESSOR_ARCHITECTURE_MIPS - Windows NT 3.51 PROCESSOR_ARCHITECTURE_ALPHA - Windows NT 4.0 и ранее PROCESSOR_ARCHITECTURE_PPC - Windows NT 4.0 и ранее PROCESSOR_ARCHITECTURE_IA64 - 64-битная версия Windows PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 - 64-битная версия Windows PROCESSOR_ARCHITECTURE_AMD64 - 64-битная версия Зарезервирован для будущего использования. dwPageSize : DWord Определяет размер страницы и степень детализации защиты страницы и блокирования. Это - размер страницы, используемый функцией VirtualAlloc. lpMinimumApplicationAddress: Pointer Указатель на самый низкий адрес памяти, доступный для приложений и библиотек динамической связи (DLLs). lpMaximumApplicationAddress: Pointer Указатель на самый высокий адрес памяти, доступный для приложений и DLLs. dwActiveProcessorMask: DWord Определяет маску, представляющую набор процессоров, конфигурированных в систему. Бит 0 - процессор 0; бит 31 - процессор 31. dwNumberOfProcessors: DWord Определяет количество процессоров в системе. dwProcessorType: DWord Устаревший элемент, предназначенный для совместимости с предыдущими версиями Windows NT (3.5 и ранее). Windows 95/98/Me: Определяет тип процессора в системе. Windows NT: Этот элемент больше не имеет значения, но сохранен для совместимости с Windows 95 и предыдущими версиями Windows NT. Необходимо использовать wProcessorArchitecture, wProcessorLevel, и wProcessorRevision элементы, чтобы определить тип процессора. Этим элементом может быть одно из следующих значений: PROCESSOR_INTEL_386 PROCESSOR_INTEL_486 PROCESSOR_INTEL_PENTIUM PROCESSOR_MIPS_R4000 - Windows NT PROCESSOR_ALPHA_21064 - Windows NT dwAllocationGranularity: DWord Определяет степень детализации распределения виртуальной памяти. wProcessorLevel : Word Windows 95 - этот элемент не поддерживается. Windows NT - определяет архитектурный уровень процессора. 2.8 Методика смешанного программирования При запуске нескольких экземпляров одного приложения, Windows загружает в оперативную память только одну копию кода и ресурсов - модуль приложения, создавая несколько отдельных сегментов данных, стека и очереди сообщений, каждый набор которых представляет из себя задачу, в понимании Windows. Копия приложения представляет из себя контекст, в котором выполняется модуль приложения. DLL - библиотека также является модулем. Она находится в памяти в единственном экземпляре и содержит сегмент кода и ресурсы, а также сегмент данных. DLL - библиотека, в отличие от приложения не имеет ни стека, ни очереди сообщений. Функции, помещенные в DLL, выполняются в контексте вызвавшего приложения, пользуясь его стеком. Но эти же функции используют сегмент данных, принадлежащий библиотеке, а не копии приложения. В силу такой организации DLL, экономия памяти достигается за счет того, что все запущенные приложения используют один модуль DLL, не включая те или иные стандартные функции в состав своих модулей. Часто, в виде DLL создаются отдельные наборы функций, объединенные по тем или иным логическим признакам, аналогично тому, как концептуально происходит планирование модулей ( в смысле unit ) в Pascal. Отличие заключается в том, что функции из модулей Pascal компонуются статически - на этапе линковки, а функции из DLL компонуются динамически, то есть в run-time. Таким образом, DLL позволяют: - избежать громоздкости исполняемого кода прикладной программы; - улучшить структурированность и модульность приложения; - уменьшить занимаемый приложением объем памяти за счет того, что несколько одновременно выполняющихся программ могут использовать одну и ту же копию подпрограммы из DLL, при этом в памяти будет физически загружена только одна копия библиотеки; - использовать любую библиотеку в любых программах, не зависимо от того, на каком языке была написана программа и библиотека. DLL являются одними из наиболее важных ключевых элементов при написании любого приложения Windows. Само ядро Windows представлено тремя большими по объему динамическими библиотеками: KERNEL.DLL, USER.DLL и GDI.DLL. Файл KERNEL.DLL, например, отвечает за управление памятью, процессами и потоками; USER.DLL содержит функции интерфейса пользователя, необходимые для создания окон и обработки сообщений Windows; на GDI.DLL возложена работа с графикой. Общее количество используемых самой Windows динамических библиотек составляет порядка двух тысяч. В курсовом проекте также используется методика смешанного программирования. Так подынтегральные функции, используемые для расчета интегралов вынесены в отдельную динамическую библиотеку functions.dll. Численные методы вынесены также в отдельную библиотеку integrals.dll. В основной программе используется динамическая загрузка dll-библиотек. Весь процесс загрузки библиотек вынесен в отдельную процедуру, листинг которой приведен на рисунке 10. procedure TMainForm.LoadDlls; var x: real; begin IntegralsDll:=LoadLibrary('Integrals.dll'); FunctionsDll:=LoadLibrary('Functions.dll'); if IntegralsDll=0 then begin Application.MessageBox('Не найден модуль ''Integrals.dll''. Работа приложения будет прекращена', 'Ошибка!!!', MB_Ok or MB_ICONERROR); Application.Terminate; end; if FunctionsDll=0 then begin Application.MessageBox('Не найден модуль ''Functions.dll''. Работа приложения будет прекращена', 'Ошибка!!!', MB_Ok or MB_ICONERROR); Application.Terminate; end; @Simpson:=GetProcAddress(IntegralsDLL,'Simpson'); @CountTrap:=GetProcAddress(IntegralsDLL,'CountTrap'); if (@CountTrap=nil) or (@Simpson=nil) then begin Application.MessageBox('Ошибка в модуле ''Integrals.dll''. Работа приложения будет прекращена', 'Ошибка!!!', MB_Ok or MB_ICONERROR); Application.Terminate; end; @Integral1Function:=GetProcAddress(FunctionsDLL,'Integral1Function'); @Integral2Function:=GetProcAddress(FunctionsDLL,'Integral2Function'); if (@Integral1Function=nil) or (@Integral1Function=nil) then begin Application.MessageBox('Ошибка в модуле ''Functions.dll''. Работа приложения будет прекращена', 'Ощибка!!!', MB_Ok or MB_ICONERROR); end; 2.9 Контроль неквалифицированных действий пользователя В приложении предусмотрен контроль за неквалифицированными действиями пользователя. Программа разработана таким образом, чтобы при любых действиях пользователя не возникало сбоя в программе. Выполнение данной задачи достигалось путем использования структурной обработки исключительных ситуаций - системы, позволяющей программисту при возникновении ошибки (исключительной ситуации) связаться с кодом программы, подготовленным для обработки такой ошибки. Это выполняется с помощью языковых конструкций, которые как бы “охраняют” фрагмент кода программы и определяют обработчики ошибок, которые будут вызываться, если что-то пойдет не так в “охраняемом” участке кода. В данном случае понятие исключительной ситуации относится к языку и не нужно его путать с системными исключительными ситуациями (hardware exceptions), такими как General Protection Fault. Исключительные ситуации в Delphi же независимы от “железа”, не используют прерываний и используются для обработки ошибочных состояний, с которыми подпрограмма не готова иметь дело. Системные исключительные ситуации, конечно, могут быть перехвачены и преобразованы в языковые исключительные ситуации, но это только одно из применений языковых исключительных ситуаций. При традиционной обработке ошибок, ошибки, обнаруженные в процедуре обычно передаются наружу (в вызывавшую процедуру) в виде возвращаемого значения функции, параметров или глобальных переменных (флажков). Каждая вызывающая процедура должна проверять результат вызова на наличие ошибки и выполнять соответствующие действия. Часто, это просто выход еще выше, в более верхнюю вызывающую процедуру и т.д. : функция A вызывает B, B вызывает C, C обнаруживает ошибку и возвращает код ошибки в B, B проверяет возвращаемый код, видит, что возникла ошибка и возвращает код ошибки в A, A проверяет возвращаемый код и выдает сообщение об ошибке либо решает сделать что-нибудь еще, раз первая попытка не удалась. Структурная обработка исключительной ситуации замещает ручную обработку ошибок автоматической, сгенерированной компилятором системой уведомления. В приведенном выше примере, процедура A установила бы “охрану” со связанным обработчиком ошибки на фрагмент кода, в котором вызывается B. B просто вызывает C. Когда C обнаруживает ошибку, то создает (raise) исключительную ситуацию. Специальный код, сгенерированный компилятором и встроенный в Run-Time Library (RTL) начинает поиск обработчика данной исключительной ситуации. При поиске “защищенного” участка кода используется информация, сохраненная в стеке. В процедурах C и B нет такого участка, а в A - есть. Если один из обработчиков ошибок, которые используются в A, подходит по типу для возникшей в C исключительной ситуации, то программа переходит на его выполнение. При этом, область стека, используемая в B и C, очищается; выполнение этих процедур прекращается. Если в A нет подходящего обработчика, то поиск продолжается в более верхнем уровне, и так может идти, пока поиск не достигнет подходящего обработчика ошибок среди используемых по умолчанию обработчиков в RTL. Обработчики ошибок из RTL только показывают сообщение об ошибке и форсированно прекращают выполнение программы. Любая исключительная ситуация, которая осталась необработанной, приведет к прекращению выполнения приложения. Без проверки возвращаемого кода после каждого вызова подпрограммы, код программы должен быть более простым, а скомпилированный код - более быстрым. При наличии исключительных ситуаций подпрограмма B не должна содержать дополнительный код для проверки возвращаемого результата и передачи его в A. B ничего не должна делать для передачи исключительной ситуации, возникшей в C, в процедуру A - встроенная система обработки исключительных ситуаций делает всю работу. Данная система называется структурной, поскольку обработка ошибок определяется областью “защищенного” кода; такие области могут быть вложенными. Выполнение программы не может перейти на произвольный участок кода; выполнение программы может перейти только на обработчик исключительной ситуации активной программы. Пример использования структурной обработки исключительных ситуаций с использованием блока try-except в процедуре TMainForm.btnSimpsonRunClick приведен на рисунке 11. try a:=StrToFloat(edSimpA.Text); b:=StrToFloat(edSimpB.Text); n:=StrToInt(edSimpN.Text); if a>b then begin Application.MessageBox('Нижний предел больше верхнего', 'Ошибка!',MB_OK or MB_ICONError); exit; end; except on EConvertError do begin Application.MessageBox('Ошибка ввода численных значений', 'Ошибка!',MB_OK or MB_ICONError); exit; end; end; Также в программе применяется методика создания и обработки пользовательской исключительной ситуации. Так в модуле evalComp.pas создается класс EvalException, являющийся потомком класса EAbort. В процессе работы с модулем может произойти генерация исключительной ситуации, которую в свою очередь будет обрабатывать вызывающий модуль (в нашем случае процедура TEvalForm.btnOkClick). Листинг примера работы с пользовательскими исключительными ситуациями приведен на рисунке 12. type EvalException = class(EAbort) end; function myfac(x,y:real):real; var begin if x<0 then begin raise EvalException.Create(''); halt; end; if x = 0 then myfac := 1 else end; procedure TEvalForm.btnOkClick(Sender: TObject); begin Dispose(calc, done); try new(calc, init(edEval.Text)); Close; except on EvalException do ShowMessage('Ошибка в формуле'); end; end; Кроме того, в программе для предотвращения возникновения непредвиденных ситуаций применяется защищенный блок try-finally-end. Листинг приведен на рисунке 13. procedure TChart.SaveToFile(filename: string); var temporary: TPicture; begin temporary:=TPicture.Create; try temporary.Bitmap.Width:=width; temporary.Bitmap.Height:=height; Temporary.Bitmap.Canvas.CopyRect(Temporary.Bitmap.Canvas.ClipRect,MainCanvas, MainCanvas.ClipRect); Temporary.SaveToFile(filename); finally temporary.Destroy; end; end; 3. ЭЛЕМЕНТЫ ИНТЕРФЕЙСА ПРОГРАММНОГО КОМПЛЕКСА 3.1 Шаблоны окон На рисунках 12 и 13 изображено главное окно программы, которое может изменять свой вид в зависимости от выбранной закладки. На рисунке 14 изображено окно, предназначенное для ввода произвольной функции. На рисунке 15 представлена форма окна отображающего сведения о системе. Окно на рисунке 16 изображено окно сведений о разработчике.
Рисунок 12 - Главное окно программы - закладка «Расчет интегралов»
Рисунок 13 - Главное окно программы - закладка «Построение графика»
Рисунок 14 - Окно «Произвольная функция»
Рисунок 15 - Окно отображающее информацию о текущей системе
Рисунок 16 - Окно сведений о программе Все компоненты, которые расположены на формах представленных на рисунках 12-16, описаны в таблицах 1-4. 3.2 Структурно-функциональная схема программного комплекса Файл формы - MainUnit.pas Имя формы - MainForm Заголовок - Курсовая работа по СПр Назначение формы - ввод исходных данных для вычисления интегралов, для отрисовки графика зависимости значения интеграла от значения верхнего предела интегрирования при фиксированном нижнем пределе, вывод на экран полученного графика, полученных результатов расчета интегралов и вызов дополнительных форм, демонстрирующих работу API-функций, формы для ввода произвольной функции, формы для получения информации о разработчике, а также вызова справки в стиле Windows. В таблице 1 представлен перечень компонентов содержащихся на форме. Таблица 1 - Описание главной формы приложения |
Имя компонента в модуле | Назначение компонента | События компонента | Назначение обработчиков событий | Примечания | | cbSimpFunct, cbTrapFunct | Компонент ComboBox предназначенный для выбора подинтегральной функции | - | - | - | | edSimpA, edSimpB, edTrapA, edTrapB | Поля для ввода изменения границ интегрирования | - | - | - | | edSimpN | Поле для ввода числа разбиений в методе Симпсона | - | - | - | | edTrapEPS | Поля для ввода точности вычислений в методе трапеций | - | - | - | | edSimpResult, edTrapResult | Поля для вывода результатов интегрирования | - | - | - | | btnSimpsonRun | Кнопка для расчета интеграла методом Симпсона | onClick | Сначала производиться проверка на наличие верхней и нижней границ. Далее проверка на то, чтобы нижняя граница была меньше или равна верхней. Контроль записи вещественных чисел. В случае прохождения всех вышеперечисленных проверок--расчет методом Симпсона и выдача в поле вывода результата. Вывод значения интеграла в edSimpResult. | MessageBox('Нижний предел больше верхнего', 'Ошибка!',MB_OK or MB_ICONError); MessageBox('Ошибка ввода численных значений', 'Ошибка!',MB_OK or MB_ICONError) | | btnTrapRun | Кнопка для расчета интеграла методом трапеций | onClick | Сначала производиться проверка на наличие верхней и нижней границ, проверка на то, чтобы нижняя граница была меньше или равна верхней. Контроль записи вещественных чисел.--расчет методом трапеций и выдача в поле вывода результата. Вывод значения интеграла в TrapResult. | MessageBox('Нижний предел больше верхнего', 'Ошибка!',MB_OK or MB_ICONError); MessageBox('Ошибка ввода численных значений', 'Ошибка!',MB_OK or MB_ICONError) | | imInt1, imInt2 | Image для отображения интегралов 1 и 2 | - | - | - | | PageControl | Компонент TPageControl, для управления закладками | - | - | - | | ChartBox | Компонент Image для отрисовки графиков | OnMouseDown | Выполняется проверка какая клавиша нажата - левая или правая - устанавливается соответствующий флаг - и в результате принимается решение о начале масштабирования либо перемещения графика | - | | | | OnMouseMove | Выполняется проверка флага нажатия кнопки мыши и в результате: если нажата левая клавиша - продолжение перемещения, правая - продолжение масштабирования | - | | | | OnMouseUp | Выполняется проверка флага нажатия кнопки мыши и в результате: если нажата левая клавиша - окончание перемещения и снятие флага, правая - окончание масштабирования и снятие флага | - | | SavePictureDialog | Компонент страницы DIALOGS служащий для сохранения изображения графика в виде отдельного файла. | Execute | Вызов стандартного окна сохранения файлов | | | MainMenu | Главное меню программы состоящее из разделов: «Файл», «Фукции», «Сервис», «Помощь» | - | - | - | | mmSave | Пункт меню для сохранения графика | onClick | Вызов стандартного окна сохранения графика | | | mmExit | Пункт меню для выхода из программы | onClick | Выход программы | | | mmIntFunct1 | Пункт меню для отображения/скрытия графика подынтегральной функции 1 | onClick | Отображает/скрывает график подынтегральной функции 1 | | | mmIntFunct2 | Пункт меню для отображения/скрытия графика подынтегральной функции 2 | onClick | Отображает/скрывает график подынтегральной функции 2 | | | mmIntegral1 | Пункт меню для отображения/скрытия графика интеграла 1 | onClick | Отображает/скрывает графикинтеграла 1 | | | mmEval | Пункт меню для открытия окна ввода произвольной функции | onClick | Вызывает окно ввода произвольной функции (форма EvalForm) | | | mmGrid | Пункт меню для установки сетки на графике | onClick | Разрешает/запрещает отрисовку сетки на графике | | | mmSysInfo | Пункт меню для вывода информации о системе | onClick | Выводит окно с информацией о системе (форма SystemInfoForm) | | | mmClipCursor | Пункт меню для использования функции ClipCursor | onClick | Демонстрирует использование функции ClipCursor | | | mmHelp | Пункт меню для вызова помощь | onClick | | | | mmAbout | Пункт меню для вывода окна информации о разработчике | onClick | Вызов формы FormAbout с информацией о разработчике | | | |
Файл формы - evalForm.pas Имя формы - EvalForm Заголовок - Произвольная функция Описание - форма предназначена для ввода произвольной пользовательской функции, отображении/скрытия ее графика. В таблице 2 представлен перечень компонентов содержащихся на форме. Таблица 2 - Описание формы ввода произвольной функции |
Имя компонента в модуле | Назначение компонента | События компонента | Назначение обработчиков событий | Примечания | | edEval | Поле для ввода произвольной функции | - | - | - | | cbEval | CheckBox для отображения/скрытия графика произвольной функции | - | - | - | | btnOk | Функция принятия изменений в произвольной функции | onClick | Выполняется проверка введенной функции, если функция соответствует правилам, то происходит изменение произвольной функции, иначе выводится сообщение | ShowMessage('Ошибка в формуле'); | | |
Файл формы - SysInfo.pas Имя формы - SystemInfoForm Заголовок - Информация о системе Описание - форма предназначена для вывода информации о текущей системе Таблица 3 - Описание формы информации о системе |
Имя компонента в модуле | Назначение компонента | События компонента | Назначение обработчиков событий | | SystemInfoForm | Форма для отображения информации о системе | onCreate | Вызывается функция GetSystemInfo и результат заносится в поля формы | | leProcessorType, leProcessorArchitecture, leProcessorLevel, leAllocationGranularity, lePageSize, leMinimumApplicationAddress, leMaximumApplicationAddress, leActicveProcessorMask, leNumberOfProcessor | Компоненты для отображения информации о системе | | | | |
Файл формы - About.pas Имя формы - AboutForm Заголовок - О программе Описание - форма предназначена для вывода информации о разработчике Таблица 4 - Описание формы информации о разработчике |
Имя компонента в модуле | Назначение компонента | События компонента | Назначение обработчиков событий | Примечания | | meAabout | Поле для вывода информации о разработчике | - | - | - | | btnOk | Кнопка закрытия формы | onClick | Закрытие формы | | | |
3.3 Описание компонентов: GroupBox, SavePictureDialog 1. Компонент TGroupBox Модуль - StdCtrls Описание: TGroupBox используется для оформления внешнего вида приложения и для группировки установленных в форму компонентов по смыслу. Все компоненты в форме можно разделить по функциональным назначениям и разместить в таких компонентах. Удобен при назначении порядка перехода по компонентам с помощью кнопки Tab. Заголовок этого компонента изменяется свойством Caption. Приведем иерархию классов для компонента TGroupBox TObject -> TPersistent -> TComponent -> TWinControl -> TCustomControl -> TCustomGroupBox -> TGroupBox Основные свойства, методы и события для этого компонента приведены в таблицах 5,6 и 7. Таблица 5 - Основные свойства компонента ТGroupBox |
Наименование | Описание | | property Components[Index: Integer]: TComponent; | Список всех компонентов, для которых данный компонент является владельцем. | | property Brush: TBrush; | Определяет цвет и шаблон для отрисовки фона копмонента. | | property ClientOrigin: TPoint; | Возвращает координаты экрана в пикселях левого верхненго угла клиентской области компонента. | | property TabOrder: TTabOrder; | Отображает номер в последовательности при переходе по компонента с помощью | | property Controls[Index: Integer]: TControl; | Список всех дочерних компонентов | | |
Таблица 6 - Основные методы компонента ТGroupBox |
Наименование | Описание | | procedure Broadcast(var Message); | Посылает сообщение каждому из дочерних компонентов | | function CanFocus: Boolean; dynamic; | Возвращает значение, может ли компонент принимать фокус. | | Procedure InsertControl(AControl: TControl); | Добавляет компонент в список дочерних компонентов данного | | function FindChildControl(const ControlName: string): TControl; | Возвращает указатель на дочерний компонент по его имени. | | procedure SetFocus; virtual; | Устанавливает фокус на компонент | | |
Таблица 7 - Основные события компонента ТGroupBox |
Наименование | Описание | | property OnEnter: TNotifyEvent; | Событие вызывается когда компонент получает фокус | | property OnExit: TNotifyEvent; | Событие вызывается когда компонент теряет фокус | | property OnClick: TNotifyEvent; | Событие вызывается когда происходит клик на компоненте | | property OnDblClick: TNotifyEvent; | Событие вызывается при двойном нажатии левой кнопки мыши на компоненте | | property OnMouseDown: TMouseEvent; | Событие вызывается когда происходит нажатие кнопки мыши при установленном на компоненте указателе мыши | | |
2. Компонент TSavePictureDialog Модуль - ExtDlgs Описание: Компонент TSavePictureDialog отображает модальное диалоговое окно для выбора имени и сохранения графических файл. Этот компонент похож на компонент TSaveDialog, за исключением того, что он включает в себя квадратное окно предварительного просмотра. Если выбранная картинка может отображаться с использованием компонента TPicture, то она отображается в области предварительного просмотра; поддерживаемые типы файлов включают в себя точечные рисунки Windows (.BMP), иконки (.ICO), Windows метафайлы (.WMF), и расширенный метафайл Windows (.EMF). Если выбранный файл не может быть отображен, в области предварительного просмотра появляестя надпись “(None)”. Иерархия компонента: TObject -> TPersistent -> TComponent -> TCommonDialog -> TOpenDialog -> TOpenPictureDialog -> TSavePictureDialog Пример использования данного компонента в программе приведен на рисунке 17. procedure TMainForm.mmSaveClick(Sender: TObject); begin if SavePictureDialog.Execute then Charter.SaveToFile(SavePictureDialog.FileName); end; Основные свойства, методы и события для этого компонента приведены в таблицах 8,9 и 10. Таблица 8 - Основные свойства компонента ТGroupBox |
Наименование | Описание | | property DefaultExt: String; | Устанавливает расширение файлов используемое по умолчанию | | property FileName: TFileName; | Определяет имя последнего выбранного файла | | property Filter: String; | Определяет маску файлов доступную в текущем диалоге | | property Title: String; | Определяет заголовок текущего диалога | | property InitialDir: String; | Определяет текущую директорию при открытии диалога | | |
Таблица 9 - Основные методы компонента ТGroupBox |
Наименование | Описание | | function Execute: Boolean; override; | Открывает диалоговое окно | | function GetStaticRect: TRect; virtual; | Определяет координаты зарезервированной области диалогового окна | | |
Таблица 10 - Основные события компонента ТGroupBox |
Наименование | Описание | | property OnCanClose: TCloseQueryEvent; | Происходит когда пользователь пытается закрыть диалоговое окно | | property OnFolderChange: TNotifyEvent; | Происходит при смене директории | | property OnIncludeItem: TIncludeItemEvent; | Происходит перед тем, как выбранный файл добавляется в список | | property OnTypeChange: TNotifyEvent; | Происходит когда типы файлов, отображаемых в диалоговом окне изменяются | | |
4. ТЕСТОВЫЕ ВЫЗОВЫ ПРОГРАММЫ Ниже приведены примеры тестовых вызовов программы: рисунок 18 - пример отображения графика первого интеграла с переменным верхним пределом, рисунок 19 - примеры расчета первого и второго интеграла с заданными параметрами точности вычислений. На рисунке 20 представлен пример исключительной ситуации, вызванной неверным задание границ интегрирования. На рисунке 21 - пример вызова API-функции GetSystemInfo, отображающей информацию о текущей системе.
Рисунок 18 - Построение графика интеграла Рисунок 19 - Примеры расчета интегралов
Рисунок 20 - Тестовый вызов исключительной ситуации
Рисунок 21 - Тестовый вызов API-функции GetSystemInfo Для проверки правильности выполненных расчетов интегралов, представленных на рисунке 19, и отображения графика первого интеграла с переменным верхним пределом приведем пример вычисления интеграла и расчета графика выполненных в программе Mathcad Professional 2000, представленном на рисунке 22. Рисунок 22 - Решение задачи в Mathcad Как видно из рисунка, значения интегралов рассчитанных в разрабатываемой программе и в программе Mathcad Professional 2000 практически сходятся, что говорит правильности решения поставленной задачи. 5. ОПИСАНИЕ РАЗРАБОТКИ СПРАВОЧНОЙ СИСТЕМЫ Для создания справочной системы я использовал программу DotCHM. Эта программа на лету создает справочные системы нескольких стандартов: 16-разрядная справка, 32-разрядная справка, chm-справка и справка для Windows CE. В DotCHM можно создавать полностью рабочий справочный файл, с поиском, обзором и содержанием, за считанные минуты. Все, что требуется это набрать текст справки. Создав новый проект справочной системы, создаю стандартное содержание. Затем создаю список разбиений справки на пункты, заполняю эти пункты, добавляю нужные изображения, ссылки и т.д. Связываю все разделы с содержанием и компилирую.
Рисунок 23 - Пример вызова справки ЗАКЛЮЧЕНИЕ Разработанная программа предоставляет возможности по вычислению интегралов с помощью численных методов с достаточно большой степенью точности, что подтверждается проведением аналогичных расчетов в профессиональной математической программе Mathcad Professional 2000. Кроме того, программа предоставляет возможность ввода произвольных функций, вычисления их интегралов и построения графиков функций. Данная программа может быть использована в учебных целях. При разработке данной программы были приобретены навыки: - разработки программ в среде программирования Delphi - использования методики смешанного программирования - использования динамической компоновки dll-библиотек - программной реализации численных методов для вычисления определенных интегралов - написания 16-ти разрядного Help-а под Windows ПЕРЕЧЕНЬ ССЫЛОК 1. Турчак Л.И. Основы численных методов: Учеб. пособие. - М.: Наука, Гл. ред. физ. -мат. лит., 2002. - 320 с 2. Стив Т., Ксавье П. Delphi6 руководство разработчика.-М.: Вильямс, 2005г.- 1112с. 3. Дан Эпплман. Win32 API и Visual Basic для профессионалов.-М.: Питер, 2001г.- 1256с. ПРИЛОЖЕНИЕ А Листинг dll-библиотеки integrals.dll library integrals; uses SysUtils, Classes; {$R *.res} type IntegralFunction= function (x: real; var y: real): boolean; function Simpson(MainFunction: IntegralFunction;a,b:real;n: integer; var Res: real): boolean; var s, h, x,y: real; i: integer; begin Result:=true; try s:=0; h:=(b-a)/n; for i:=0 to n do begin x:=a+h*i; if (i=0) or (i=n) then if MainFunction(x,y) then s:=s+y else Result:=false else if i mod 2 = 0 then if MainFunction(x,y) then s:=s+2*y else Result:=false else if MainFunction(x,y) then s:=s+4*y else Result:=false; end; except Simpson:=false; end; Res:=s*h/3; end; function CountTrap(MainFunction: IntegralFunction; a,b, eps: real; var Res: real): boolean; function PTrap(MainFunction: IntegralFunction; a,b:real; DivNo: Integer; var Res: real): boolean; var x1, x2,y1,y2,y3,dx,sum: real; i: integer; begin PTrap:=true; try sum:=0; dx:=(b-a)/DivNo; for i:=1 to DivNo-1 do begin x1:=a+dx*i; if MainFunction(x1,y1) then sum:=sum+y1 else Raise EAbort.Create(''); end; sum:=sum*2; if MainFunction(a,y1) and MainFunction(b,y2) then sum:=sum+y1+y2 else Raise EAbort.Create(''); Res:=sum*dx/2; except PTrap:=False; end; end; {-----} var T: integer; i1, i2: real; begin countTrap:=true; try if PTrap(MainFunction,a,b,2,i1) and PTrap(MainFunction,a,b,4,i2) then begin T:=4; while abs(i1-i2)>eps do begin if PTrap(MainFunction,a,b,t,i1) and PTrap(MainFunction,a,b,t*2,i2) then t:=t*2 else EAbort.Create(''); T:=T*2; end; end else EAbort.Create(''); Res:=(i1+i2)/2; except CountTrap:=false; end; end; exports Simpson index 1; exports CountTrap index 2; begin end. ПРИЛОЖЕНИЕ Б Листинг dll-библиотеки functions.dll library functions; uses SysUtils, Classes; {$R *.res} function Integral1Function(x: real; var y: real):boolean; begin Result:=true; try y:=1/sqrt(2+0.5*x*x) except result:=false; end; end; function Integral2Function(x: real; var y: real):boolean; begin Result:=true; try y:=sin(2*x)/sqr(x) except result:=false; end; exports Integral1Function; exports Integral2Function; begin end. ПРИЛОЖЕНИЕ В Листинг модуля chart.pas unit Chart; interface uses Graphics, SysUtils, Classes; const BorderTop=10; BorderBottom=40; BorderLeft=40; BorderRight=10; type GraphFunction = function(x: real; var y: real): boolean; TChartFunction = class private MainFunction: GraphFunction; FColor: TColor; FShow: boolean; public constructor Create(f: GraphFunction); published property Color: TColor read FColor write FColor; property Show: boolean read FShow write FShow; end; TChart = class private functions: TStringList; ChartBitmap: TBitmap; MainCanvas: TCanvas; bgBrush: TBrush; gridPen: TPen; AxisPen: TPen; Width: integer; Height: integer; FScale: real; FStep: real; FShowGrid: boolean; xx0, yy0: integer; nsteps: integer; x0, y0: integer; procedure DrawGrid; procedure DrawFunction(funct: TChartFunction); procedure DrawFunctions; procedure PutPixel(x,y: integer; Color: TColor); procedure OutTextCenter(s: string; x, y: integer); public constructor Create(Canvas: TCanvas); procedure AddFunction(f: TChartFunction; Ident: String); function DelFunction(s: string): boolean; procedure ReDraw; procedure ShiftHor(value: integer); procedure ShiftVer(value: integer); procedure Rescale(xvalue, yvalue: integer; Maximize: boolean); procedure GetXY(x,y: integer; var x1,y1: real); procedure SaveToFile(filename: string); published property ShowGrid: boolean read FShowGrid write FShowGrid; end; implementation { TChart } constructor TChart.Create(Canvas: TCanvas); begin functions:=TStringList.Create; MainCanvas:=Canvas; ChartBitmap:=TBitmap.Create; bgBrush:=TBrush.Create; bgBrush.Color:=clWhite; gridPen:=TPen.Create; gridPen.Style:=psDot; AxisPen:=TPen.Create; AxisPen.Width:=2; AxisPen.Style:=psInsideFrame; AxisPen.Color:=clRed; Width:=MainCanvas.ClipRect.Right-MainCanvas.ClipRect.Left; Height:=MainCanvas.ClipRect.Bottom-MainCanvas.ClipRect.Top; ChartBitmap.Width:=Width; ChartBitmap.Height:=Height; FShowGrid:=true; xx0:=40+trunc((width-50)/2); yy0:=10+trunc((height-50)/2); x0:=xx0; y0:=yy0; NSteps:=20; FScale:=20; FStep:=(width/fscale)/nsteps; ReDraw; end; procedure TChart.DrawFunction(funct: TChartFunction); var x, y: real; x1,y1,x2,y2: integer; a,b: boolean; f: GraphFunction; begin x:=-(x0/FScale); a:=false; f:=funct.MainFunction; while (x0+x*FScale)<(Width-BorderRight) do begin if f(x,y) then begin x1:=round(x0+x*FScale); y1:=round(y0-y*FScale); if (x1>BorderLeft) and (x1<width-BorderRight) and (y1>BorderTop) and (y1<height-BorderBottom) then begin PutPixel(x1,y1, funct.Color); end; end; x:=x+0.01; end; end; procedure TChart.OutTextCenter(s: string; x, y: integer); begin x:=x-round(MainCanvas.TextWidth(s)/2); y:=y-round(MainCanvas.TextHeight(s)/2); MainCanvas.TextOut(x,y,s); end; procedure TChart.DrawGrid; var x, y: integer; k: real; s: string; begin With MainCanvas do begin Brush.Assign(bgBrush); FillRect(ClipRect); begin if FShowGrid then Pen.Assign(GridPen) else Pen.Style:=psClear;; x:=x0 mod trunc(FScale*FStep); while x<(width-BorderRight) do end; procedure TChart.ReDraw; begin DrawGrid; DrawFunctions; end; procedure TChart.ShiftHor(value: integer); begin x0:=x0+value; ReDraw; end; procedure TChart.ShiftVer(value: integer); begin y0:=y0+value; ReDraw; end; procedure TChart.AddFunction(f: TChartFunction; Ident: String); begin functions.AddObject(Ident,f); ReDraw; end; procedure TChart.DrawFunctions; var i: integer; begin for i:=0 to functions.Count-1 do if TChartFunction(functions.Objects[i]).Show then DrawFunction(TChartFunction(functions.Objects[i])); end; begin if x>BorderLeft then begin MoveTo(x,BorderTop); LineTo(x, Height-BorderBottom); k:=(x-x0)/FScale; s:= FloatToStrF(k,ffGeneral,4,2); OutTextCenter(s, x, height-round(BorderBottom/2)); end; x:=x+trunc(FStep*FScale); end; y:=y0 mod trunc(FScale*FStep); while y<(height-BorderBottom) do begin if y>BorderTop then begin MoveTo(BorderLeft,y); LineTo(Width-BorderRight, y); k:=(y0-y)/FScale; s:= FloatToStrF(k,ffGeneral,4,2); OutTextCenter(s,round(BorderLeft/2), y); end; y:=y+trunc(FStep*FScale); end; end; // юЄЁшёютър ъююЁфшэрЄэvї юёхщ Pen.Assign(AxisPen); if (x0>BorderLeft) and (x0<(width-BorderRight)) then begin MoveTo(x0, BorderTop); lineto(x0, height-BorderBottom-1); end; if (y0>BorderTop) and (y0<(Height-BorderBottom)) then begin Moveto(BorderLeft,y0); lineTo(width-BorderRight-1, y0); end; Pen.Assign(gridPen); Pen.Style:=psSolid; Brush.Style:=bsClear; Rectangle(40, 10, Width-10, height-40); Brush.Style:=bsSolid; end; end; procedure TChart.PutPixel(x, y: integer; Color: TColor); var i, j: integer; begin with MainCanvas do for i:=x to x+1 do for j:=y to y+1 do MainCanvas.Pixels[i,j]:=Color; function TChart.DelFunction(s: string): boolean; label 1; var i: integer; begin result:=false; for i:=0 to functions.Count-1 do if functions.Strings[i]=s then begin result:=true; functions.Delete(i); goto 1; end; 1: end; procedure TChart.Rescale(xvalue, yvalue: integer; Maximize: boolean); var mx, my: Real; begin if xvalue*yvalue<>0 then begin mx:=(width-borderleft-borderright)/xvalue; my:=(height-bordertop-borderbottom)/yvalue; if Maximize then if mx<my then FScale:=FScale*mx else FScale:=FScale*my else if mx<my then FScale:=FScale/mx else FScale:=FScale/my; FStep:=(width/FScale)/NSteps; ReDraw; end; end; procedure TChart.GetXY(x, y: integer; var x1, y1: real); begin x1:=(x-x0)/FScale; y1:=(y0-y)/FScale; end; procedure TChart.SaveToFile(filename: string); var temporary: TPicture; begin temporary:=TPicture.Create; temporary.Bitmap.Width:=width; temporary.Bitmap.Height:=height; Temporary.Bitmap.Canvas.CopyRect( Temporary.Bitmap.Canvas.ClipRect, MainCanvas, MainCanvas.ClipRect); Temporary.SaveToFile(filename); temporary.Destroy; end; { TChartFunction } constructor TChartFunction.Create(f: GraphFunction); begin MainFunction:=f; Show:=true;end;end.
Страницы: 1, 2
|