Text: |
ФІО = Горбаченко В.А.
Запитання:Дослідити залежності координати та швидкості простого гармонійного осциля¬тора від часу. Результатом роботи програми має бути таблиця чисел залежності координати х(t) і швидкості V(t)=dx/dt та графіки залежності х(t) і V(t). Значення параметрів вводити із клавіатури.
Короткий опис модельованої системи для варіанта 6
Тіло ковзає за горизонтальною поверхнею без
тертя. Точка х = 0 є точкою рівноваги (рис. 6.7).
Сила, що діє на тіло з координатою х: F = -kx.
Рівняння руху тіла: d2x/dt2=-((w0)^2)*x (7)
Де ((w0)^2) = k / m;
РОЗВ'ЯЗОК даного рівняння має вигляд: x(t)=Acos(w0t+б) (А і б - амплітуда та початкова фаза).
Період коливань: T = (2*PI/w)= (2*PI/sqrt(k/m)) частота w = 1 /Т. Повна енергія: Е=0.5mv^2+0.5kx2. < т
Для розв'язку рівняння (7) використати алгоритм Ейлера-Кромера. Введення пара¬метрів, побудову графіків і реалізацію методу Ейлера-Кромера оформити у вигляді процедур. Побудувати часові залежності потенційної і кінетичної енергії за один період (за допомогою окремої процедури).
==================================
Решение на BORLAND PASCAL 7.0
==================================
program lab7;
uses graph, crt, dos;
const dotsAmount = 100;
type
dotsArray = array [1..dotsAmount] of real;
var gd,gm,i,tempInt:integer;
t1, t2, dt, t, y, k, m, a, w, tempReal:real;
x, v, Ek, Ep:dotsArray;
tempstr:string;
procedure drawGraph(var arr:dotsArray; a, t1, t2:real; oy:string);
begin
setlinestyle(0,0,2);
setcolor(lightgray);
for i:=0 to 10 do
begin
tempInt := round(40+i*(getmaxx-80)/10);
line(tempInt, 20, tempInt, getmaxy-20);
tempReal := i*(t2-t1)/10;
str(tempReal:0:1, tempstr);
outtextxy(tempInt, getmaxy-15, tempstr);
end;
for i:=-2 to 2 do
begin
if i = 0 then
begin
setcolor(white);
outtextxy(getmaxx-30, round(40+0.5*(getmaxy-60)), 't');
end;
tempInt := round(80+(i+2)*(getmaxy-60)/5);
line(40, tempInt, getmaxx-20, tempInt);
tempReal := -i*2*a/5;
str(tempReal:0:1, tempstr);
outtextxy(0, tempInt, tempstr);
setcolor(lightgray);
end;
setcolor(red);
tempReal := 80+(0.4*(getmaxy-60)); {x=0}
for i:=1 to dotsAmount-1 do
begin
line(round(40+dt*(i-1)/(t2-t1)*(getmaxx-80)),
round(tempReal+arr[i]/a*(20-tempReal)),
round(40+dt*(i)/(t2-t1)*(getmaxx-80)),
round(tempReal+arr[i+1]/a*(20-tempReal)));
end;
setcolor(white);
line(40, 20, 40, getmaxy-20);
outtextxy(20, 30, oy);
end;
function stepin(num:real):integer;
var temp:integer;
ts:string;
begin
temp:=0;
if num<1 then
begin
while num<1 do
begin
num:=num*10;
dec(temp);
end;
end;
if num>=10 then
begin
while num>10 do
begin
num:=num/10;
inc(temp);
end;
end;
stepin:=temp;
end;
procedure drawEnergyGraph(var Ek, Ep:dotsArray; a,w:real);
begin
setlinestyle(0,0,2);
setcolor(lightgray);
str(stepin(a), tempstr);
for i:=0 to 10 do
begin
tempInt := round(80+i*(getmaxx-120)/10);
line(tempInt, 20, tempInt, getmaxy-20);
tempReal := i*(t2-t1)/10;
str(tempReal:0:1, tempstr);
outtextxy(tempInt, getmaxy-15, tempstr);
end;
for i:=0 to 5 do
begin
if i = 0 then
begin
setcolor(white);
outtextxy(getmaxx-30, getmaxy-15, 't');
end;
tempInt := round(20+(5-i)*(getmaxy-40)/5);
line(80, tempInt, getmaxx-20, tempInt);
setcolor(lightgray);
tempReal := i*a/5;
str(tempReal:0:-stepin(a)*(i div 1), tempstr);
outtextxy(0, round(20+(5-i)*(getmaxy-40)/5), tempstr);;
end;
setcolor(red);
tempReal := getmaxy-20; {x=0}
for i:=1 to dotsAmount-1 do
begin
line(round(80+dt*(i-1)/(t2-t1)*(getmaxx-120)),
round(tempReal+Ek[i]/a*(20-tempReal)),
round(80+dt*(i)/(t2-t1)*(getmaxx-120)),
round(tempReal+Ek[i+1]/a*(20-tempReal)));
end;
outtextxy(20, 30, 'Ek');
setcolor(green);
tempReal := getmaxy-20; {x=0}
for i:=1 to dotsAmount-1 do
begin
line(round(80+dt*(i-1)/(t2-t1)*(getmaxx-120)),
round(tempReal+Ep[i]/a*(20-tempReal)),
round(80+dt*(i)/(t2-t1)*(getmaxx-120)),
round(tempReal+Ep[i+1]/a*(20-tempReal)));
end;
outtextxy(20, 50, 'Ep');
setcolor(white);
line(80, 20, 80, getmaxy-20);
end;
procedure getParameters(var k,m,t1,t2,a:real);
begin
repeat
Write('k = ');
read(k);
until k>0;
repeat
Write('m = ');
read(m);
until m>0;
{repeat
Write('t1 = ');
read(t1);
until t1>=0; }
t1:=0;
repeat
Write('t2 = ');
read(t2);
until t2>t1;
repeat
Write('X0 = ');
read(a);
until a>0;
end;
procedure countKoords(var x,v,Ep,Ek:dotsArray; k,m,t1,t2,a:real);
begin
dt:=(t2-t1) / dotsAmount;
w:=sqrt(k/m);
x[1]:=a;
v[1]:=0;
Ep[1]:=0.5*k*a*a;
for i:=2 to dotsAmount do
begin
x[i]:=x[i-1]+dt*v[i-1];
v[i]:=v[i-1]-dt*w*w*x[i];
Ep[i]:=0.5*k*x[i]*x[i];
Ek[i]:=0.5*m*v[i]*v[i];
end;
{for i:=1 to dotsAmount do
begin
t:=(i-1)*dt;
x[i]:=a*cos(w*t);
Ep[i]:=0.5*k*x[i]*x[i];
end;
for i:=1 to dotsAmount do
begin
t:=(i-1)*dt;
v[i]:=-a*w*sin(w*t);
Ek[i]:=0.5*m*v[i]*v[i];
end;}
end;
procedure printTable(arr:dotsArray; t1,t2:real; par:string);
begin
dt:=(t2-t1) / dotsAmount;
for i:=1 to dotsAmount do
begin
t:=(i-1)*dt;
writeln('t = ', t:0:3, '; ', par, ' = ', arr[i]:0:2);
if i mod 15 = 0 then
begin
writeln('press any key to continue...');
readkey;
end;
end;
end;
function findAmpl(var arr:dotsarray):real;
var i:integer;
temp:real;
begin
temp:=abs(arr[1]);
for i:=2 to dotsamount do
begin
if (abs(arr[i])>temp) then temp:=abs(arr[i]);
end;
findampl:=temp;
end;
begin
gd:=VGA;
gm:=VGAHi;
getParameters(k,m,t1,t2,a);
w:=sqrt(k/m);
countKoords(x,v,Ep,Ek,k,m,t1,t2,a);
PrintTable(x, t1, t2, 'x');
readkey;
InitGraph(gd,gm,'c:\tp7\');
drawGraph(x, findampl(x), t1, t2, 'x');
readkey;
CloseGraph;
PrintTable(v, t1, t2, 'v');
readkey;
InitGraph(gd,gm,'c:\tp7\');
drawGraph(v, findampl(v), t1, t2, 'V');
readkey;
CloseGraph;
InitGraph(gd,gm,'c:\tp7\');
drawEnergyGraph(Ek, Ep, findampl(Ek), w);
readkey;
CloseGraph;
end.
==================================
Решение на BORLAND C++ 3.0
==================================
#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <iostream.h>
#include <math.h>
// USER AREA
#define MAXSTR 255
#define dotsAmount 100
struct dotsArray{
double array[dotsAmount+1];
};
int gd, gm, i, tempInt;
double t1,t2,dt,t,y,k,m,a,w,tempReal;
dotsArray x, v, Ek, Ep;
char tempstr[MAXSTR];
// USER AREA
//==========================================================================
void getParameters(double &k, double &m, double &t1, double &t2, double &a)
{
do
{
cout<<"k = ";
cin>>k;
} while (k<=0);
do
{
cout<<"m = ";
cin>>m;
} while (m<=0);
t1=0;
do
{
cout<<"t2 = ";
cin>>t2;
} while (t2<=t1);
do
{
cout<<"X0 = ";
cin>>a;
} while (a<=0);
}
//--------------------------------------------------------------------------
void countKoords(dotsArray &x,dotsArray &v, dotsArray &Ep, dotsArray &Ek, double k, double m, double t1, double t2, double a)
{
dt=(t2-t1) / dotsAmount;
w=sqrt(k/m);
x.array[1]=a;
v.array[1]=0;
Ep.array[1]=0.5*k*a*a;
for (int i = 2 ; i <= dotsAmount ; i++)
{
x.array[i]=x.array[i-1]+dt*v.array[i-1];
v.array[i]=v.array[i-1]-dt*w*w*x.array[i];
Ep.array[i]=0.5*k*x.array[i]*x.array[i];
Ek.array[i]=0.5*m*v.array[i]*v.array[i];
}
return ;
}
//--------------------------------------------------------------------------
void printTable(dotsArray &arr, double t1, double t2, char *par)
{
dt=(t2-t1) / dotsAmount;
for (int i = 1 ; i <=dotsAmount ; i++)
{
t=(i-1)*dt;
printf("t = %0.3f ; %s = %0.3f\n\r",t,par,arr.array[i]);
if ( i % 15 == 0)
{
printf("press any key to continue...\n\r");
getch();
}
}
}
//--------------------------------------------------------------------------
double findAmpl(dotsArray arr)
{
double temp;
temp=fabs(arr.array[1]);
for (int i = 2 ; i <= dotsAmount ; i++)
{
if (fabs(arr.array[i])>temp) temp=fabs(arr.array[i]);
}
return temp;
}
//--------------------------------------------------------------------------
void drawGraph(dotsArray &arr, double a, double t1, double t2, char *oy)
{
setlinestyle(0,0,2);
setcolor(LIGHTGRAY);
for (int i = 0 ; i <= 10 ; i++)
{
tempInt = ceil(40+i*(getmaxx()-80)/10);
line(tempInt, 20, tempInt, getmaxy()-20);
tempReal = i*(t2-t1)/10;
sprintf(tempstr,"%0.1f",tempReal);
outtextxy(tempInt, getmaxy()-15, &tempstr[0]);
}
for (i = -2 ; i <= 2 ; i++)
{
if (i == 0)
{
setcolor(WHITE);
outtextxy(getmaxx()-30, ceil(40+0.5*(getmaxy()-60)), "t");
}
tempInt = ceil(80+(i+2)*(getmaxy()-60)/5);
line(40, tempInt, getmaxx()-20, tempInt);
tempReal = -i*2*a/5;
sprintf(tempstr,"%0.1f",tempReal);
outtextxy(0, tempInt, &tempstr[0]);
setcolor(LIGHTGRAY);
}
setcolor(RED);
tempReal = 80+(0.4*(getmaxy()-60)); //x=0
for (i = 1 ; i < dotsAmount ; i++)
{
line(ceil(40+dt*(i-1)/(t2-t1)*(getmaxx()-80)),
ceil(tempReal+arr.array[i]/a*(20-tempReal)),
ceil(40+dt*(i)/(t2-t1)*(getmaxx()-80)),
ceil(tempReal+arr.array[i+1]/a*(20-tempReal)));
}
setcolor(WHITE);
line(40, 20, 40, getmaxy()-20);
outtextxy(20, 30, &oy[0]);
}
//--------------------------------------------------------------------------
int stepin(double num)
{
int temp;
char ts[MAXSTR];
temp=0;
if (num<1)
{
while (num<1)
{
num=num*10;
temp--;
}
}
if (num>=10)
{
while (num>10)
{
num=num/10;
temp++;
}
}
return temp;
}
//--------------------------------------------------------------------------
void drawEnergyGraph(dotsArray &Ek, dotsArray &Ep, double a, double w)
{
setlinestyle(0,0,2);
setcolor(LIGHTGRAY);
sprintf(tempstr,"%i",stepin(a));
for (int i = 0 ; i <= 10 ; i++)
{
tempInt = ceil(80+i*(getmaxx()-120)/10);
line(tempInt, 20, tempInt, getmaxy()-20);
tempReal = i*(t2-t1)/10;
sprintf(tempstr,"%0.1f",tempReal);
outtextxy(tempInt, getmaxy()-15, &tempstr[0]);
}
for (i = 0 ; i <= 5 ; i++)
{
if (i == 0)
{
setcolor(WHITE);
outtextxy(getmaxx()-30, getmaxy()-15, "t");
}
tempInt = ceil(20+(5-i)*(getmaxy()-40)/5);
line(80, tempInt, getmaxx()-20, tempInt);
setcolor(LIGHTGRAY);
tempReal = i*a/5;
// str(tempReal:0:-stepin(a)*(i div 1), tempstr);
sprintf(tempstr,"%-0.2e",tempReal);
outtextxy(0, ceil(20+(5-i)*(getmaxy()-40)/5), tempstr);;
}
setcolor(RED);
tempReal = getmaxy()-20;// {x=0}
for (i = 1 ; i < dotsAmount ; i++ )
{
line(ceil(80+dt*(i-1)/(t2-t1)*(getmaxx()-120)),
ceil(tempReal+Ek.array[i]/a*(20-tempReal)),
ceil(80+dt*(i)/(t2-t1)*(getmaxx()-120)),
ceil(tempReal+Ek.array[i+1]/a*(20-tempReal)));
}
outtextxy(20, 30, "Ek");
setcolor(GREEN);
tempReal = getmaxy()-20; // {x=0}
for (i = 1 ; i < dotsAmount ; i++)
{
line(ceil(80+dt*(i-1)/(t2-t1)*(getmaxx()-120)),
ceil(tempReal+Ep.array[i]/a*(20-tempReal)),
ceil(80+dt*(i)/(t2-t1)*(getmaxx()-120)),
ceil(tempReal+Ep.array[i+1]/a*(20-tempReal)));
}
outtextxy(20, 50, "Ep");
setcolor(WHITE);
line(80, 20, 80, getmaxy()-20);
}
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
//==========================================================================
int main()
{
clrscr();
int gdriver = DETECT, gmode, errorcode;
getParameters(k,m,t1,t2,a);
w=sqrt(k/m);
countKoords(x,v,Ep,Ek,k,m,t1,t2,a);
printTable(x, t1, t2, "x");
getch();
initgraph(&gdriver, &gmode, "");
/* read result of initialization */
errorcode = graphresult();
if (errorcode != grOk) /* an error occurred */
{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
exit(1); /* return with error code */
}
drawGraph(x, findAmpl(x), t1, t2, "x");
getch();
closegraph();
printTable(v, t1, t2, "v");
getch();
initgraph(&gdriver, &gmode, "");
/* read result of initialization */
errorcode = graphresult();
if (errorcode != grOk) /* an error occurred */
{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
exit(1); /* return with error code */
}
drawGraph(v, findAmpl(v), t1, t2, "V");
getch();
closegraph();
initgraph(&gdriver, &gmode, "");
/* read result of initialization */
errorcode = graphresult();
if (errorcode != grOk) /* an error occurred */
{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
exit(1); /* return with error code */
}
drawEnergyGraph(Ek, Ep, findAmpl(Ek), w);
getch();
closegraph();
return 0;
}
====================================
|