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

Методическое пособие 366

.pdf
Скачиваний:
5
Добавлен:
30.04.2022
Размер:
1.03 Mб
Скачать

терфейс). Вместо многоточий должен стоять полный путь к рабочей папке, в которой лежат описываемые sce- и sci-файлы) q0=[0;0;0;0;0;0];

p0=[0;0;0;0;0;0];

(задаются начальные значения для решения задачи Коши. В данном случае q0 – вектор начальных значений обобщѐнных координат исследуемого тела (3 координаты центра масс тела и 3 угла поворота), а p0 – вектор из начальных значений производных указанных обобщѐнных координат).

scf(333);clf();

(создаѐтся пустое графическое окно с номером 333)

H=build_body();

(рисует в созданном графическом окне исследуемое тело, описание функции будет приведено ниже при разборе файла с функциями графического интерфейса)

ax=gca();

(создаѐтся дескриптор осей)

ax.axes_visible=["on" "on" "on"]; ax.grid=[1 1 1]; ax.x_label.text="X"; ax.y_label.text="Y"; ax.z_label.text="Z";

(задаются свойства осей: первая строчка отвечает за видимость осей: вектор из трѐх значений on означает, что все три оси будут видны в созданном графическом окне, вторая строчка означает, что по всем трѐм осям будет нанесена сетка, а последние три строчки вводят обозначения для каждой из осей). Результатом этих команд является изображение в графическом окне (рис. 5)

9

Рис. 5. Графический интерфейс

Способ получения тела и вертикальной линии будет описан при описании функции build_body. y=[q0(1);p0(1);q0(2);p0(2);q0(3);p0(3);q0(4);p0(4);q0(5);p0(5);q 0(6);p0(6)];

(формируется начальное значение вектора состояния решаемой системы 12 дифференциальных уравнений первого порядка) y0=y;y1=y;

(начальное значение вектора состояния системы помещается в промежуточные переменные, которые будут использоваться в дальнейшем)

init=%t;state_changed=%f;

(задаются начальные значения для двух логических переменных: переменная init отвечает за то, была ли произведена инициализация состояния системы: true, если была и false, если не была, соответственно в начальный момент времени, т.е. в момент инициализации она полагается равной true; переменная state_changed показывает, поменялись ли компоненты вектора

10

состояния системы или нет: если нет, то false, если да, то true; в начальный момент, когда состояние ещѐ не менялось, она рав-

на true)

global y0 y1 state_changed init

(поскольку вышеуказанные 4 переменные будут использоваться в дальнейшем, они объявляются глобальными)

Файл model.sci (этот файл содержит функции, описывающие динамику исследуемого тела):

function qpdot=body_dyn(t, qp)

(на вход функции подаѐтся время начала интервала интегрирования системы дифференциальных уравнений (переменная t) и значение вектора состояния интегрируемой системы на момент t; на выходе функции правая часть системы уравнений на момент времени t (переменная qpdot))

q1=qp(1);

q2=qp(3);

q3=qp(5);

q4=qp(7);

q5=qp(9);

q6=qp(11);

(6 обобщѐнных координат в момент времени t) p1=qp(2);

p2=qp(4);

p3=qp(6);

p4=qp(8);

p5=qp(10);

p6=qp(12);

(6 производных обобщѐнных координат в момент времени t) a21=0.1; a22=100; a23=6*10^(-3)*sin(2*%pi*t); a24=9.815*4*10^(-5)*sin(2*%pi*t); a43=4.4*10^(-3)*sin(2*%pi*t); a44=9.815*2*10^(- 5)*sin(2*%pi*t);

11

a61=a21; a62=100; a63=2.6*10^(-3)*sin(2*%pi*t); a64=a43*a44/9.815; a65=a23*a24/9.815; a66=- 16*%pi*%pi*10^(-5)*sin(2*%pi*t); a67=-8*%pi*%pi*10^(- 5)*sin(2*%pi*t); a68=16*%pi*10^(-5)*cos(2*%pi*t); %pi*10^(-5)*cos(2*%pi*t); a610=7.64*10^2; a611=1.27*10^4; a612=2*10^3;

a81=0.1; a82=400; a123=-12*%pi*%pi*10^(-5)*sin(2*%pi*t);

(записываются численные значения коэффициентов правой части системы)

qpdot=[p1; -a21*p1-a22*q1-a23+a24; p2; -a21*p2-a22*q2-a43+a44; p3;

-a61*p3-a62*q3-a63+a64-a65+a66*q1-a67*q2+a68*p1-a69*p2- a610*q3*q3-a611*(q1*q1+q2*q2)-a612*(q4*q4+q5*q5);

p4; -a81*p4-a82*q4-a67; p5; -a81*p5-a82*q5-a66; p6; -a81*p6-a82*q6-a123];

(записывается правая часть системы) endfunction

function R=euler(psi, theta, phi)

(функция, на вход которой подаются три угла Эйлера, на выходе матрица ориентации двух трѐхгранников, записанная через углы Эйлера)

cpsi=cos(psi);spsi=sin(psi); ct=cos(theta);st=sin(theta); cphi=cos(phi);sphi=sin(phi);

R=[cpsi*ct*cphi-spsi*sphi,-cpsi*ct*sphi-spsi*cphi, cpsi*st; spsi*ct*cphi+cpsi*sphi,-spsi*ct*sphi+cpsi*cphi, spsi*st;

12

-st*cphi ,st*sphi, ct] endfunction

function R=eulerm1(psi, theta, phi)

(всѐ то же самой, только на выходе получается матрица, транспонированная к матрице, полученной при выполнении предыдущей функции)

cpsi=cos(psi);spsi=sin(psi); ct=cos(theta);st=sin(theta); cphi=cos(phi);sphi=sin(phi);

R=[cpsi*cphi*ct-spsi*sphi, cpsi*sphi+spsi*cphi*ct, -cphi*st; -spsi*cphi-cpsi*sphi*ct, cpsi*cphi-spsi*sphi*ct, sphi*st;

cpsi*st,

spsi*st,

ct ];

endfunction

 

 

Файл model_gui.sci (этот файл содержит функции, отвечающие за графический интерфейс):

function [H]=build_body()

(функция, при помощи которой исследуемое тело появляется в графическом окне; возвращает дескриптор графического объекта, коим в данном случае выступает поверхность, изображающая исследуемое тело)

n=21;

[X,Y,Z]=body_facets(body_profile,n)

(в результате действия этой функции, которая будет описана ниже, получаются 3 матрицы. Эти матрицы используются в дальнейшем в функции plot3d, которая изображает тело. Изображение получается путѐм объединения множества элементов поверхности. Каждый элемент представляет собой многоугольник; координаты вершин каждого из многоугольников и являются элементами трѐх матриц X, Y, Z. Число вершин каждого из многоугольников есть число строк каждой из матриц; число столбцов каждой из матриц есть число элементов, составляющих поверхность. Переменная n представляет собой число точек, которые составляют «скелет» тела, в каждой из горизонтальных плоскостей, проходящих через тело; число

13

этих плоскостей представлено ниже и обозначено переменной np, причѐм 2 из этих плоскостей проходят через нижнюю и верхнюю точки тела соответственно)

N=n-1; np=1+size(X,2)/N drawlater()

(N обозначает число элементов поверхности, которые получены разбиением тела вертикальными плоскостями, проходящими через точки, образующие «скелет» тела) f=gcf();f.color_map=graycolormap(N);

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

s=[((N/2)):(N-1),N:-1:((N/2)+1)];

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

clf(),plot3d(X,Y,list(Z,ones(1,np-1).*.s))

(строится исследуемое тело, элемент поверхности с вершинами X(:,i), Y(:,i), Z(:,i) имеет свой цвет, числовой эквивалент которого равен s(i))

H=gce();

(дескриптор графического объекта – поверхности)

H.hiddencolor=-1;

(внутренность тела раскрашена так же, как и внешняя сторона)

H.color_mode = -1;

(отрицательное значение этого параметра означает, что границы элементов, составляющих поверхность, не изображаются)

H.clip_state = 'off';

(изображение поверхности не обрезается при выходе за какуюлибо область рисунка)

H.user_data=[0 0 0 0 0 0];

14

(в этом поле сохраняются обобщѐнные координаты тела) x=-2.5:0.05:2.5;

param3d(zeros(x),zeros(x),x);

(рисуется вертикальная линия от z = -2.5 до z = 2.5) e=gce();e.thickness=2;

(увеличивается толщина линии для лучшего визуального эффекта)

a=gca();

(дескриптор осей)

a.data_bounds=[-1.5 -1.5 -1.5;1.5 1.5 1.5];

(это поле обозначает границы значений на осях, первые 3 значения – нижние границы значений, на осях X, Y, Z соответственно, вторые 3 значения – верхние границы) a.axes_bounds=[0 0 0.8 1];

(положение осей: первые 2 числа – положение левого верхнего угла рисунка, вторые 2 числа – ширина и высота рисунка в отношении к его максимальному размеру. Все 4 числа должны лежать в промежутке [0,1])

a.box='off';

(куб, образованный тремя осями, не изображается) a.isoview="on";

(включается изометрический вид осей) a.rotation_angles=[76 45];

(обозначает сферические координаты воображаемой точки, с которой наблюдатель смотрит на рисунок)

drawnow() endfunction

function [zp, ro]=body_profile()

(на выходе функции массивы из координат точек, расположенных на сечении тела вертикальной плоскостью, проходящей через центр тела (в данном случае тело – сфера, значит сечение - окружность): zp – массив с Z-координатами точек, ro – массив с расстояниями от каждой из точек до вертикальной прямой, проходящей через центр тела)

15

ttheta = linspace(0, %pi, 35); ro = (0.45*sin(ttheta))';

zp = (0.45*cos(ttheta))'; endfunction

таким образом, получается 35 точек. function [X, Y, Z]=body_facets(prof, n)

(на входе – данные, полученные от предыдущей функции и число точек, составляющих «скелет» тела в каждой из горизонтальных плоскостей, проходящих через каждую из 35 точек, полученных в предыдущей функции, на выходе – матрицы X, Y, Z, используемые в функции build_body)

[zp,ro]=prof(); np=size(ro,'*'); t=linspace(0,2*%pi,n); x=ro*cos(t); y=ro*sin(t); z=zp*ones(t);

(в итоге x, y, z содержат матрицы с координатами точек, составляющих «скелет» сферы, т.е. они представляют собой мат-

рицы 35*n, где n=21 (см. описание build_body))

После этого образовываются искомые матрицы X, Y, Z с координатами вершин элементов поверхности:

Iz=([0;0;1;1]*ones(1,np-1)+ones(4,1)*(1:(np-1))).*.ones(1,n-1); It=ones(1,np-1).*.([0;1;1;0]*ones(1,n-1)+ones(4,1)*(0:(n-2))); I=matrix(Iz+np*It,-1,1);

X=matrix(x(I),4,-1);

Y=matrix(y(I),4,-1);

Z=matrix(z(I),4,-1); endfunction

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

function body_gui()

16

(функция, которая создаѐт графический интерфейс) global body_controls

fig=gcf(); w=fig.axes_size;

(массив из двух элементов – ширина и высота графического окна)

m=20; lslider=150;h=20; lv=40;

xs=w(1)+lslider+lv+m+10; xv=xs+lslider+10; yx=w(2)-(m+h);

(переменные, определяющие местоположение элементов графического интерфейса, их размеры и интервалы между ними)

Xplane_title = uicontrol( ...

"parent"

, fig,...

"style"

, "text",...

"string"

, "Xplane",...

"units"

, "pixels",...

"position"

, [xs yx+h lslider h],...

"fontunits"

, "points",...

"fontsize"

, 9,...

"horizontalalignment" , "center", ...

"background"

, [1 1 1], ...

"tag"

, "XplaneTitle" ... );

После выполнения этой функции в указанном месте (определяется значением, казанном в поле position) созданного графического окна (дескриптор созданного окна fig указан в поле parent) появляется текст (что указано в поле style); сама надпись указывается в поле string, размер текста и единицы измерения указаны в полях fontsize и fontunits соответственно. В поле position первые 2 элемента – это левый нижний угол блока, внутри которого располагается текст, а вторые 2 числа – ширина

17

блока и его высота, единицы измерения этих чисел указаны в поле units; в поле background - цвет фона в блоке (в данном случае белый), а в поле horizontalalignment – способ выравнивания текста внутри блока (влево, вправо или по центру)

Slider_Xplane=uicontrol("parent",fig,.. "style","slider",..

"Min",0,..

"Max",100,.. "Value",0,.. "units","pixels",..

"position"

, [xs yx lslider h],...

"tag"

, "Xplane", ...

"callback"

, "update_xplane()" ...

);

 

После выполнения этой функции появится ползунок (что указано в поле style), задаются максимальное и минимальное значения (в данном случае 0 и 100), его значение в настоящий момент времени (поле Value). При движении ползунка вызывается функция update_xplane, что отображено в поле callback.

Ползунок расположится под надписью Xplane, что достигается путѐм задания соответствующих значений координат в поле position

Value_Xplane = uicontrol("parent",fig,.. "Position" , [xv yx lv h],...

"Style" , "text",...

"String" , "0",...

"BackgroundColor",[1 1 1]);

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

Таким образом, после выполнения этих действий в графическом окне появится элемент, который наглядно показывает, как меняется одна из обобщѐнных координат рассматриваемого тела (X-координата центра масс тела). Далее, такие же дей-

18