Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Практический курс математического и компьютерного моделирования. Учебно-практическое пособие

.pdf
Скачиваний:
0
Добавлен:
08.09.2026
Размер:
2 Мб
Скачать
III. Приемы и методы программирования
чтобы облегчить в будущем работу по отладке и сопровождению программы. Кроме этого, конечно, нужно отражать все изменения программного кода в прилагающейся к проекту документации.
Следующие советы могут помочь повысить быстродейст­вие программного кода.
а) по возможности, старайтесь исключить операции с пла- вающей точкой, так как они выполняются много медленнее, чем
манипуляции с целыми величинами.
б) операции целочисленного умножения и деления лучше заменить сложением и вычитанием или, что еще лучше, сдви­гами. Например, вместо
3 + k shl 1 + k;
поскольку выполняется равенство 11 = 23 + 2 + 1.
k := k*11; можно использовать k := k shl
в) так как перед каждым вызовом процедуры или функции ее параметры помещаются в стек, а затем изымаются оттуда, то процедуры лучше спроектировать так, чтобы они имели как можно меньше параметров. Если фактические параметры имеют большой объем, то нужно передавать процедурам не сами эти параметры, а указатели на них.
г)
если есть возможность не выполнять какие-либо расчеты в реальном времени, можно их предварительно подготовить, а затем уже использовать (см. листинги).
д) вместо применения процедур и функций VCL
тесь соответствующими функциями Windows API
38
пользуй-
39
. В самых
критических случаях можно использовать Assembler, про­граммирование на котором более трудоемко по сравнению с языками высокого уровня, но обеспечивает максимальную скорость выполнения программы. Даже встроенный в Delphi Assembler дает значительные преимущества по сравнению с использованием функций Object Pascal и VCL. Кроме того, можно вынести ассемблерный код в отдельный модуль и под­ключать к проекту
38
Visual Component Library — библиотека визуальных компонент Delphi, функции и процедуры которой содержат вызовы стандартных функций API Windows и значительно упрощают работу с последними.
39
Application Programming Interface — программный интерфейс при- ложений, множество системных функций Windows.
, предварительно откомпилировав его.
111
Математическое и компьютерное моделирование
Следует отметить, что самым лучшим способом оптимиза­ции является выбор более эффективного алгоритма — пу­зырьковая сортировка будет всегда идти медленно, несмотря на все программистские ухищрения. По проблемам, связан­ным с построением и анализом вычислительных алгоритмов, рекомендуются книги [40; 32].
III.5. Анимация
Анимация изображений может потребоваться при решении многих задач компьютерного моделирования. Рассмотрим способы решения некоторых проблем, возникающих при этом.
Алгоритм анимации в самом общем виде можно описать как цикл: построить изображение кадра — сделать временную задержку — стереть изображение кадра, построить картинку следующего кадра. При этом, если построение и стирание кар­тинки отображать непосредственно обычно возникает
40
неприятное для глаз дрожание изображе-
на экран монитора, то
ния. Так, в программе примера 1 (см. листинги), несмотря на очень простое изображение, при некоторых значениях вход­ных параметров модели можно заметить мерцание.
В компьютерной графике эту проблему решают обычно при помощи двойной буферизации (double buffering). Эта тех­ника заключается в том, что вначале изображение строится во вспомогательной
области памяти, называемой задним буфе-
ром кадра, а затем оно выводится на экран — передний буфер кадра. Таким образом, в цикле анимации картинка в переднем
буфере, через некоторый временной интервал, постоянно под­меняется изображением из заднего буфера кадра.
В качестве примера создадим программу, изображающую двигающийся по круговой орбите черный круг. В качестве заднего буфера используем объект класса
40
Зависит от характеристик hardware, сложности картинки и длины
временного интервала кадра.
TBitmap.
112
III. Приемы и методы программирования
// файл animUnit.pas unit animUnit; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Menus; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - type TanimForm = class(TForm) Panel1 : TPanel; runButton : TButton; Edit_delay : TEdit; Edit_alpha_h : TEdit; StaticText1 : TStaticText; StaticText2 : TStaticText; Timer1 : TTimer; StaticText7 : TStaticText; Edit_interval : TEdit; StaticText8 : TStaticText; StaticText9 : TStaticText; MainMenu1 : TMainMenu; menuFile : TMenuItem; menuExit : TMenuItem; menuAbout : TMenuItem; procedure runButtonClick( Sender: TObject ); procedure FormActivate( Sender: TObject ); procedure Timer1Timer( Sender: TObject ); procedure Edit_intervalChange( Sender: TObject ); procedure Edit_delayChange( Sender: TObject ); procedure menuAboutClick( Sender: TObject ); procedure menuExitClick( Sender: TObject ); private alpha : double; // угол вращения; alpha_h : double; // приращение угла; center_x : word; // центр center_y : word; // вращения; r : word; // радиус-вектор; r0 : word; // радиус круга;
113
Математическое и компьютерное моделирование
4
bitmap : TBitmap; // буфер для кадра; delay_anim : LongWord; // задержка смены кадров; procedure frame; // кадр анимации; public { Public declarations } end; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - var animForm: TanimForm; implementation {$R *.dfm} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // прорисовка кадра анимации и стирание предыдущего; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - procedure TanimForm.frame; var a0, b0 : word; begin bitmap.Canvas.Brush.Color := clWhite; bitmap.Canvas.Pen.Color := clWhite; a0 := center_x + round( r*cos( alpha - PI/alpha_h ) ); b0 := center_y - round( r*sin( alpha - PI/alpha_h ) ); bitmap.Canvas.Ellipse( a0 - r0, b0 - r0, a0 + r0, b0 + r0 ); bitmap.Canvas.Pen.Color := clBlack; bitmap.Canvas.Ellipse( center_x - r, center_y - r, center_x + r, center_y + r ); bitmap.Canvas.Ellipse( center_x - 3, center_y - 3, center_x + 3, center_y + 3 ); bitmap.Canvas.Brush.Color := clBlack; a0 := center_x + round( r*cos( alpha ) ); b0 := center_y - round( r*sin( alpha ) ); bitmap.Canvas.Ellipse( a0 - r0, b0 - r0, a0 + r0, b0 + r0 ); end; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // задержка на s, точность измерения интервала времени // не превосходит 0.055 секунды (1 "тик" CPU) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - procedure Delay( s : Double ); var tick0 : LongWord;
11
III. Приемы и методы программирования
5
begin tick0 := getTickCount; repeat //Application.ProcessMessages; until ( ( ( getTickCount - tick0 ) ) >= s ); end; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // пуск/останов анимации; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - procedure TanimForm.runButtonClick( Sender: TObject ); begin try // обработка ошибки ввода приращения alpha; alpha_h := StrToFloat( Edit_alpha_h.Text ); except on EConvertError do begin ShowMessage( 'Неверный ввод данных' + #13#10 + 'проверьте десятичную ./, ' ); exit; end; end; // конец обработки ошибок ввода; Timer1.Enabled := not Timer1.Enabled; if ( Timer1.Enabled ) then runButton.Caption := 'STOP' else runButton.Caption := 'RUN'; end; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // инициализация параметров // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - procedure TanimForm.FormActivate( Sender: TObject ); begin alpha := 0; center_x := ( animForm.ClientWidth - Panel1.Width ) div 2; center_y := animForm.ClientHeight div 2; r := ( animForm.ClientWidth - Panel1.Width ) div 3; r0 := ( animForm.ClientWidth - Panel1.Width ) div 24; Timer1.Enabled := FALSE; bitmap := TBitmap.Create; bitmap.Width := animForm.ClientWidth;
11
Математическое и компьютерное моделирование
6
bitmap.Height := animForm.ClientHeight; animForm.Color := clWhite; delay_anim := StrToInt( Edit_delay.Text ); end; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // анимация // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - procedure TanimForm.Timer1Timer( Sender: TObject ); begin if ( alpha > 2*PI ) then alpha := alpha - 2*PI; frame; // кадр подготовлен; animForm.Canvas.Draw( 0, 0, bitmap ); // кадр показан; delay( delay_anim ); // задержка; alpha := alpha + PI/alpha_h; end; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // изменение интервала таймера // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - procedure TanimForm.Edit_intervalChange( Sender: TObject ); var inter: word; begin if ( Timer1.Enabled ) then exit; try // обработка ошибочного ввода для интервала таймера; inter := StrToInt( Edit_interval.Text ); except on EConvertError do begin ShowMessage( 'Неверный ввод данных,' + #13#10 + 'нужно - натуральное число' ); exit; end; end; // конец обработки ошибок ввода; Timer1.Interval := inter; end; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // изменение величины задержки смены кадров // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - procedure TanimForm.Edit_delayChange( Sender: TObject );
11
III. Приемы и методы программирования
7
begin try // обработка ошибочного ввода для задержки; delay_anim := StrToInt( Edit_delay.Text ); except on EConvertError do begin ShowMessage( 'Неверный ввод данных,' + #13#10 + 'нужно - натуральное число' ); exit; end; end; // конец обработки ошибок ввода; end; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - procedure TanimForm.menuAboutClick(Sender: TObject); begin ShowMessage( 'Анимация' + #13#10 + 'учебный пример' + #13#10 + 'В. Зенкин, 2005 г.' ); end; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - procedure TanimForm.menuExitClick(Sender: TObject); begin close; end; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end. // конец файла animUnit.pas
Объект bitmap, используемый в качестве заднего буфера, об­ладает рядом полезных свойств, в том числе, например, имеет метод для сохранения изображения на диске в виде графического файла, что позволит, сохранив все кадры в файлах, позднее (при желании), очень просто создать анимационный фильм. На ри­сунке III. 1 показано окно программы на этапе выполнения.
Нужно
отметить особенность измерения временных про­межутков — данная программа не может получить и исполь­зовать временной интервал, меньший 55 миллисекунд. Следо­вательно, если задать интервал таймера, меньший этого значе­ния, скорость работы от этого не увеличится. Это может стать
11
Математическое и компьютерное моделирование
проблемой, особенно, если потребуется воспроизводить рабо­ту моделируемой системы в реальном времени. Кроме этого, если обработчик «тика» таймера не успеет выполнить все дей­ствия за установленный интервал, то последующие вызовы этого обработчика помещаются в очередь. Такая ситуация мо­жет привести к тому, что программа будет работать на разных компьютерах с различной
скоростью.
Рис. III.1
Есть разные способы решения этой проблемы. Например, можно использовать мультимедийный таймер (модуль MMSystem). Это позволит обрабатывать события с частотой, которая ограничивается только мощностью аппаратного обес­печения компьютера, причем кадры, которые не успели вос­произвестись, накапливаться в очереди не будут. Запускается и останавливается мультимедийный таймер специальными функциями — API
timeSetEvent и timeKillEvent соответственно
(подробнее см. справку в Microsoft Multimedia Programmer's Reference из входящего в стандартную поставку Delphi MS SDK Help Files).
В случаях более сложных изображений, чем рассмотрен­ное, особенно трехмерных, при программировании анимации можно использовать средства графических библиотек OpenGL или DirectX.
118
IV. ЗАДАНИЯ
Решение задач — специфическое достижение разума, ра­зум же — особый дар, которым наделен человек. Способность к преодолению препятствий, к нахождению обходного манев­ра там, где не видно прямого пути, возвышает умное живот­ное над тупым, человека — над самым умным животным и талантливых людей — над другими людьми.
Д. Пойа [35]
Трудно, если не тая теорию и не применяя полученную информацию для ре­шения специальных задач и тем самым не заставляя себя об­думывать то, что было прочитано. Кроме того, мы лучше за­учиваем то, что сами открываем для себя.
невозможно изучить предмет, только чи-
Д. Кнут [32]
IV.1. Требования к оформлению работ
Лабораторная работа должна содержать следующее. а) Программу на языке высокого уровня (предпочтительно
использовать C/C++, Pascal/Object Pascal).
б) Исходные коды программы, снабженные подробными комментариями для всех алгоритмов, процедур и функций, а также фамилию автора, дату реализации.
в) Набор тестовых значений параметров и описание ре­зультатов тестирования программы с этими параметрами (не менее 4–5 вариантов).
г)
Электронную (help-файл) и/или бумажную документа-
цию, включающую:
119
Математическое и компьютерное моделирование
0
задание;
подробное описание модели, включая перечисление всех принятых упрощений и ограничений;
подробный вывод всех формул;
используемые при построении модели физические, ме­ханические, биологические и другие законы;
описание применяемых при решении уравнений модели
численных методов (если используются) с соответствующими ссылками на литературу;
— cписок использованной литературы.
Интерфейс программы с пользователем
должен быть по возможности простым и понятным («дружественным»). Кроме того, следует помнить, что пользователю, вообще говоря, никакой интерфейс сам по себе — даже самый хо­роший — не нужен, ему нужно уметь делать свое дело. Чем меньше различных действий (нажатий клавиш, щелчков мышью и т. дить для решения задачи, тем лучше. Применяйте стандарт­ные элементы GUI операционной системы ложении «бантики»
д.) пользователю программы придется произво-
41
42
неуместны. Чем меньше интерфейс
, в деловом при-
отвлекает пользователя от выполнения его работы, тем лучше. Используйте различные виды подсказок относитель­но назначения элементов управления, например — в статус­ной строке. При выполнении программой длительных про-
41
Графический пользовательский интерфейс (GUI) Windows, ко-
нечно, не самый лучший, но множество пользователей привыкли именно к нему.
42
Различные анимированные изображения, звуковые эффекты,
нестандартные меню и прочее, не относящееся напрямую к реше­нию задачи. Например, в программе для решения задачи 2.12 можно было бы реализовать трёхмерное анимированное изобра­жение сердца и сопроводить эту анимацию замечательной компо­зицией группы King Crimson «Heartbeat», но первое явно избы­точно, так как соответствующая модель не является второе — лишнее.
12
трёхмерной, а
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]