
- •1.1 Оформление программы
- •1.2 Переменные и константы
- •1.2.1 Типы
- •1.2.2 Записи (структуры)
- •V: real; // 2-я переменная, скорость
- •Var // Служебное слово для обозначения
- •1.2.3 Массивы
- •Int s[10]; // Определение массива с
- •1.2.4 Локальные и глобальные переменные
- •Implementation // Определяет внешнюю видимость этого
- •I: integer; // объявление локальной внутри процедуры
- •I:integer; // переменных, в том числе «I»
- •Void __fastcall tForm1::Button1Click(tObject *Sender)
- •Int I; // объявление локальной внутри процедуры
- •1.3 Указатели
- •I:integer;
- •Inc(k,2); // перемещение указателя вперед на 2 длины
- •1.4 Команды
- •1.5 Пользовательские процедуры и функции
- •Void __fastcall tForm1::Button1Click(tObject *Sender)
- •Int n1,n2; // объявление локальных переменных
- •1.6 Объекты программы
- •Void __fastcall tForm1::Button1Click(tObject *Sender)
- •1.7 Пример программы пользователя
- •1.7.1 Постановка задачи
- •1.7.2 Подготовка формы
- •1.7.3 Алгоритм программы
- •1.7.4 Последовательность разработки программы
- •1.7.5 Программа в Delphi
- •Interface // Определяет внешнюю видимость этого модуля
- •Implementation
- •2Перемещение объектов по форме
- •2.1 Общие сведения
- •2.1.1 Изменение положения объектов на форме
- •2.1.1.1Подготовка формы
- •2.1.1.2Блок-схема программы
- •2.1.1.3Листинг программы в среде Delphi:
- •Interface
- •Implementation
- •Void __fastcall tForm1::Button1Click(tObject *Sender)
- •Void __fastcall tForm1::Timer1Timer(tObject *Sender)
- •2.1.2 Расчет положения объекта на форме по физическим координатам моделируемого объекта
- •2.1.3 Расчет координат связанных объектов
- •2.2 Дифференциальные уравнения
- •2.2.1 Дифференциальные уравнения движения
- •2.2.2 Методика решения дифференциальных уравнений движения
- •2.2.3 Алгоритмы управления движущимся объектом
- •Xmax, Ymax, Dx, Dy: real;
Xmax, Ymax, Dx, Dy: real;
begin
// начальные условия механизма 1
Meh1.Nx:=0;
Meh1.Ny:=0;
Meh1.vx:=0;
Meh1.vy:=0;
Meh1.x1:=0;
Meh1.y1:=0;
// начальные условия механизма 2
Meh2.Ny:=0;
Meh2.vy:=0;
Meh2.y2:=0;
// Вычисление масштаба отображения
Xmax:=L+d1+d2;
Ymax:=H+h1;
Dx:=(90-10)/100*Form1.ClientWidth/Xmax;
Dy:=(70-10)/100*Form1.ClientHeight/Ymax;
if (Dy>Dx) then
begin
D:=Dx;
end
else
begin
D:=Dy;
end;
// изменение размеров Shape
Shape1.Width:=round(D*d1);
Shape1.Height:=round(D*h1);
Shape2.Width:=round(D*d2);
Shape2.Height:=round(D*h2);
// Определение левой и верхней границы перемещения
LeftMin:=round(10/100*Form1.ClientWidth);
TopMin:=round(10/100*Form1.ClientHeight);
// отображение объектов Shape на форме
Risovanie();
end;
Необходимо отметить, что для вычисления некоторых параметров объектов Shape и переменных LeftMin и TopMin целого типа применяется встроенная функция round(), которое округляет десятичные дроби до целого значения.
Для отображения Shape на форме согласно математическим моделям определим пользовательскую процедуру Risovanie, которая вычисляет формулы (2.3) и (2.4). Саму процедуру необходимо поместить впереди обработчика события Form1.OnCreate. Вызов же самой функции помещается в конце обработчика данного события (см. листинг выше).
procedure Risovanie();
begin
Form1.Shape1.Left:=round(D*Meh1.x1+LeftMin);
Form1.Shape1.Top:=round(D*Meh1.y1+TopMin);
Form1.Shape2.Left:=round(D*(Meh1.x1+d1)+LeftMin);
Form1.Shape2.Top:=round(D*(Meh1.y1+Meh2.y2)+TopMin);
end;
Для моделирования перемещения механизмов только при нажатии соответствующих кнопок, используем событие «OnMouseDown» для обработки именно нажатия кнопки, и событие «OnMouseUp» для обработки отпускания кнопки. В первом типе обработчиков необходимо задать направление движения (переменные Meh1.Nx, Meh1.Ny, Meh2.Ny), а во вторых событиях обнулить управляющие переменные. Листинг обработчиков этих событий показан ниже:
procedure TForm1.Button1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Meh1.Nx:=+1; // движение механизма 1 вправо
end;
procedure TForm1.Button2MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Meh1.Nx:=-1; // движение механизма 1 влево
end;
procedure TForm1.Button3MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Meh1.Ny:=-1; // движение механизма 1 вверх
end;
procedure TForm1.Button4MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Meh1.Ny:=+1; // движение механизма 1 вниз
end;
procedure TForm1.Button5MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Meh2.Ny:=-1; // движение механизма 2 вверх
end;
procedure TForm1.Button6MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Meh2.Ny:=+1; // движение механизма 2 вниз
end;
procedure TForm1.Button1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Meh1.Nx:=0; // остановка механизма 1
end;
procedure TForm1.Button2MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Meh1.Nx:=0; // остановка механизма 1
end;
procedure TForm1.Button3MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Meh1.Ny:=0; // остановка механизма 1
end;
procedure TForm1.Button4MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Meh1.Ny:=0; // остановка механизма 1
end;
procedure TForm1.Button5MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Meh2.Ny:=0; // остановка механизма 2
end;
procedure TForm1.Button6MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
Meh2.Ny:=0; // остановка механизма 2
end;
В обработчике события «OnTimer» объекта Timer1 необходимо реализовать алгоритм движения механизмов с учетом ускорения, замедления, ограничения максимальных перемещений и управляющих переменных.
Диаграмма движения механизма 1 по оси x представлена на рисунке 2.5. При нажатии на кнопку управляющая переменная Nx выставляется равным +1. После этого ускорение принимается равное a1max. Начинается равноускоренное движение с возрастающей скоростью. При достижении скорости значения v1ust, ускорение принимается равное 0 и механизм 1 движется с постоянной скоростью. После отпускания кнопки переменная Nx становится равной 0, знак ускорения принимается обратным знаку скорости. В последствии скорость уменьшается до значения, близкого к нулю и механизм останавливается. Алгоритм программы движения по оси x приведен на рисунке 2.6.
Рисунок
2.5 – Диаграмма движения
Рисунок 2.6 – Алгоритм управления движением
Алгоритм движения по другим осям будет аналогичным с учетом ограничений движения механизма 1 по оси y 0<Meh1.y1<H и механизма 2 по оси y 0<Meh2.y2<h1.
Алгоритм, приведенный на рисунке 2.6, достаточно сложный для реализации в программе вследствие многочисленных ветвлений. Для того, чтобы не запутаться при реализации программы необходимо правильно устанавливать отступы, показывая вложения команд, и не забывать сразу прописывать обе ветки ветвления. Для примера приведена последовательность написания программы для блоков 1-9 (рисунок 2.6).
1. Установка шаблона обработчика события «OnTimer». Выбрать объект «Timer1» на форме. В инспекторе объектов выбрать вкладку «Events». Два раза кликнуть левой кнопкой мыши на строчку «OnTimer»:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
end;
2. Объявление локальной переменной «a»:
procedure TForm1.Timer1Timer(Sender: TObject);
var
a:real;
begin
end;
3. Блок сравнения 1 (рисунок 2.6). Сразу необходимо прописать заготовки двух веток «begin-end» через else. Одинаковыми отступами показываем, что обе ветки имеют одинаковую вложенность.
procedure TForm1.Timer1Timer(Sender: TObject);
var
a:real;
begin
if Meh1.Nx=0 then
begin // кнопка отпущена
end
else
begin // кнопка нажата
end;
end;
4. Блок сравнения 2 реализуется в ветке, когда кнопка нажата. Отступом показываем, что этот блок вложен в предыдущий.
begin
if Meh1.Nx=0 then
begin // кнопка отпущена
end
else
begin // кнопка нажата
if Meh1.Nx=+1 then
begin // да
end
else
begin // нет
end;
end;
end;
6. Блок вычисления ускорения 3, блок сравнения 4 и блок обнуления ускорения 5:
begin
if Meh1.Nx=0 then
begin // кнопка отпущена
end
else
begin // кнопка нажата
if Meh1.Nx=+1 then
begin // да
end
else
begin // нет
a:=-a1max;
if Meh1.vx<=-v1ust then
begin // да
a:=0;
end; { // пустую ветку else можно не писать
else
begin // нет
end; }
end;
end;
end;
7. Блок вычисления ускорения 6, блок сравнения 7 и блок обнуления ускорения 8:
begin
if Meh1.Nx=0 then
begin // кнопка отпущена
end
else
begin // кнопка нажата
if Meh1.Nx=+1 then
begin // да
a:=+a1max;
if Meh1.vx>=v1ust then
begin // да
a:=0;
end;
end
else
begin // нет
a:=-a1max;
if Meh1.vx<=-v1ust then
begin // да
a:=0;
end; { // пустую ветку else можно не писать
else
begin // нет
end; }
end;
end;
end;
Аналогично оформляем остальные ветки алгоритма. Для движения по оси x программа будет выглядеть следующим образом:
begin
if Meh1.Nx=0 then
begin // кнопка отпущена
if Meh1.vx>0 then
begin // да вправо
a:=-a1max;
if Meh1.vx<=0.01*v1ust then
begin // да
a:=0;
Meh1.vx:=0;
end;
end
else
begin // нет влево
a:=+a1max;
if Meh1.vx>=-0.01*v1ust then
begin // да
a:=0;
Meh1.vx:=0;
end;
end;
end
else
begin // кнопка нажата
if Meh1.Nx=+1 then
begin // да
a:=+a1max;
if Meh1.vx>=v1ust then
begin // да
a:=0;
end;
end
else
begin // нет
a:=-a1max;
if Meh1.vx<=-v1ust then
begin // да
a:=0;
end; { // пустую ветку else можно не писать
else
begin // нет
end; }
end;
end;
// ограничение положения слева и справа
if ((Meh1.x1>=L) and (Meh1.Nx>=0)) or ((Meh1.x1<=0) and (Meh1.Nx<=0)) then
begin // да
a:=0;
Meh1.vx:=0;
end;
// решение дифф. уравнений по оси x механизма 1
Meh1.vx:=Meh1.vx + a*0.01;
Meh1.x1:=Meh1.x1 + Meh1.vx*0.01;
// Изменение положения Shape на форме
Risovanie();
end;
Можно запустить программу и убедиться в работоспособности перемещения механизма 1 влево и вправо с ускорением.
Полный листинг обработчика события «OnTimer» с обработкой всех перемещений:
procedure TForm1.Timer1Timer(Sender: TObject);
var
a:real;
begin
if Meh1.Nx=0 then
begin // кнопка отпущена
if Meh1.vx>0 then
begin // да вправо
a:=-a1max;
if Meh1.vx<=0.01*v1ust then
begin // да
a:=0;
Meh1.vx:=0;
end;
end
else
begin // нет влево
a:=+a1max;
if Meh1.vx>=-0.01*v1ust then
begin // да
a:=0;
Meh1.vx:=0;
end;
end;
end
else
begin // кнопка нажата
if Meh1.Nx=+1 then
begin // да
a:=+a1max;
if Meh1.vx>=v1ust then
begin // да
a:=0;
end;
end
else
begin // нет
a:=-a1max;
if Meh1.vx<=-v1ust then
begin // да
a:=0;
end; { // пустую ветку else можно не писать
else
begin // нет
end; }
end;
end;
// ограничение положения слева и справа
if ((Meh1.x1>=L) and (Meh1.Nx>=0)) or ((Meh1.x1<=0) and (Meh1.Nx<=0)) then
begin // да
a:=0;
Meh1.vx:=0;
end;
// решениe дифф. уравнений по оси x механизма 1
Meh1.vx:=Meh1.vx + a*0.01;
Meh1.x1:=Meh1.x1 + Meh1.vx*0.01;
// -------------------- Механизм 1 по оси y -----------------------------------
if Meh1.Ny=0 then
begin // кнопка отпущена
if Meh1.vy>0 then
begin // да
a:=-a1max;
if Meh1.vy<=0.01*v1ust then
begin // да
a:=0;
Meh1.vy:=0;
end;
end
else
begin // нет
a:=+a1max;
if Meh1.vy>=-0.01*v1ust then
begin // да
a:=0;
Meh1.vy:=0;
end;
end;
end
else
begin // кнопка нажата
if Meh1.Ny=+1 then
begin // да
a:=+a1max;
if Meh1.vy>=v1ust then
begin // да
a:=0;
end;
end
else
begin // нет
a:=-a1max;
if Meh1.vy<=-v1ust then
begin // да
a:=0;
end;
end;
end;
// ограничение положения слева и справа
if ((Meh1.y1>=H) and (Meh1.Ny>=0)) or ((Meh1.y1<=0) and (Meh1.Ny<=0)) then
begin // да
a:=0;
Meh1.vy:=0;
end;
// решениe дифф. уравнений по оси y механизма 1
Meh1.vy:=Meh1.vy + a*0.01;
Meh1.y1:=Meh1.y1 + Meh1.vy*0.01;
// -------------------- Механизм 2 по оси y -----------------------------------
if Meh2.Ny=0 then
begin // кнопка отпущена
if Meh2.vy>0 then
begin // да
a:=-a2max;
if Meh2.vy<=0.01*v2ust then
begin // да
a:=0;
Meh2.vy:=0;
end;
end
else
begin // нет
a:=+a2max;
if Meh2.vy>=-0.01*v2ust then
begin // да
a:=0;
Meh2.vy:=0;
end;
end;
end
else
begin // кнопка нажата
if Meh2.Ny=+1 then
begin // да
a:=+a2max;
if Meh2.vy>=v2ust then
begin // да
a:=0;
end;
end
else
begin // нет
a:=-a2max;
if Meh2.vy<=-v2ust then
begin // да
a:=0;
end;
end;
end;
// ограничение положения слева и справа
if ((Meh2.y2>=(h1-h2)) and (Meh2.Ny>=0)) or ((Meh2.y2<=0) and (Meh2.Ny<=0)) then
begin // да
a:=0;
Meh2.vy:=0;
end;
// решениe дифф. уравнений по оси y механизма 1
Meh2.vy:=Meh2.vy + a*0.01;
Meh2.y2:=Meh2.y2 + Meh2.vy*0.01;
// Изменение положения Shape на форме
Risovanie();
end;