ФІО = Горбаченко В.А. Запитання:Дослідити залежності координати та швидкості простого гармонійного осциля¬тора від часу. Результатом роботи програми має бути таблиця чисел залежності координати х(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 #include #include #include #include #include // 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; } ====================================