1. Заголовок темы должен быть информативным. В противном случае тема удаляется ... 2. Все тексты программ должны помещаться в теги [code=pas] ... [/code]. 3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали! 4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора). 5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM! 6. Одна тема - один вопрос (задача) 7.Проверяйте программы перед тем, как разместить их на форуме!!! 8.Спрашивайте и отвечайте четко и по существу!!!
Довольно долго помучавшись с интегралами, решил прикрутить к проге отрисовку графика, который будет рисовать на основе данных, берущихся из двух массивов, одна возникла неприятность: 1) соединение двух точек линией происходит некорректно 2) неправильно указывает точку (все "скапливается" около начала координат, а не находится около своих значений)
Исходный код:
Uses Graph, Crt, Dos;
Const LimEst:array[1..2,1..2] of double=((0.4,1.2), (0.8,1.6)); len:array [1..6] of double=(8,16,64,512,2048,131072); st:array[1..2] of string[20]=('# 1st Integral ','# 2nd Integral '); eps : double = 0.000000001;
Type func=function(x:double):double; res =array [1..2,1..6] of double; part=array [1..2,1..6] of longint;
Procedure Init; Var Driver, Mode, ErrorCode: smallint; Begin Driver:=detect; InitGraph(Driver,Mode,''); ErrorCode:=GraphResult; if ErrorCode<>grOK then begin Writeln(GraphErrorMsg(ErrorCode)); Halt(1); end; End;
{Первая функция} Function F1(x:double):double; Begin F1:=cos(x)/(x+2); End;
{Вторая функция} Function F2(x:double):double; Begin F2:=sqrt(0.3*x*x+2.3)/(1.8+sqrt(2*x+1.6)); End;
{Метод левых прямоугольников} Procedure LeftRectangle(var a,b:double; fn:func; e:double; l:integer); Var y,y1 : double; step,sum: double; i,n,p : longint; Begin n:=1; y:=0; y1:=0; repeat {Запоминаем кол-во разбиений} NumbPart[l,j]:=n; {Вычисляем интеграл} y:=y1; step:=(b-a)/n; sum:=0; for i:=0 to n-1 do begin sum:=sum+fn(a+i*step); end; sum:=sum*step; y1:=sum; n:=2*n; {Запоминаем результат вычислений} results[l,j]:=y1; until abs(y1-y)<=e; {Вывод} { if abs(e-0.0001)<eps then write(y1:9:4, '?,NumbPart[l,j]:4,'?); if abs(e-0.00001)<eps then write(y1:10:5, '?,NumbPart[l,j]:5,'?); if abs(e-0.000001)<eps then write(y1:10:6, '?,NumbPart[l,j]:6,'?);} End;
{Метод центральных прямогоульников} Procedure CenterRectangle(var a,b:double; fn:func; e:double; l:integer); Var y,y1 : double; step,sum: double; i,n,p : longint; Begin n:=1; y:=0; y1:=0; repeat {Запоминаем кол-во разбиений} NumbPart[l,j]:=n; {Вычисляем интеграл} y:=y1; step:=(b-a)/n; sum:=0; for i:=0 to n-1 do begin sum:=sum+fn(a+i*step+step/2); end; sum:=sum*step; y1:=sum; n:=2*n; {Запоминаем результат вычислений} results[l,j]:=y1; until abs(y1-y)<=e; {Вывод} { if abs(e-0.0001)<eps then write(y1:9:4, '?,NumbPart[l,j]:3,'?); if abs(e-0.00001)<eps then write(y1:10:5, '?,NumbPart[l,j]:3,'?); if abs(e-0.000001)<eps then writeln(y1:10:6,'?,NumbPart[l,j]:3,'?);} End;
{Рисуем таблицу} Procedure DrawTable; Begin randomize; {Тут находится таблица, ее не рисую здесь} for i:=1 to 2 do begin {Выбираем интеграл, в зависимости от i} case i of 1: begin write('? Intgr?); f:=F1; end; 2: begin write('? Intgr); f:=F2; end; end; {Запоминаем диапазон значений} left :=LimEst[i,1]; right:=LimEst[i,2]; {Считаем интеграл двумя способами, и разными точностями} for j:=1 to 6 do begin case j of 1: LeftRectangle(left,right,f,0.0001,i); 2: LeftRectangle(left,right,f,0.00001,i); 3: LeftRectangle(left,right,f,0.000001,i); 4: CenterRectangle(left,right,f,0.0001,i); 5: CenterRectangle(left,right,f,0.00001,i); 6: CenterRectangle(left,right,f,0.000001,i); end; end; { writeln('#-------#---------#----#----------#-----#----------#------#---------#---#----------#---#----------#---#'); readkey; gotoXY(whereX,whereY-1); writeln('#-------#---------#----#----------#-----#----------#------#---------#---#----------#---#----------#---#');} end; End;
{Рисуем график по данным} Procedure DrawGraph; Var i,j,u : integer; x1,y1,x2,y2: longint; sx,sy : string; l:integer; Begin {Подготовка к отрисовке графика} Init; ClearDevice; {Рисуем график} for i:=1 to 2 do begin ClearDevice; SetBkColor(Black); SetColor(Red); OutTextXY(GetMaxX-180,20,'Red - 1st Method'); SetColor(Green); OutTextXY(GetMaxX-180,30,'Green - 2nd Method'); SetColor(Magenta); OutTextXY(GetMaxX-180,10,st[i]); OutTextXY(85,10,'u,results'); OutTextXY(GetMaxX-90,GetMaxY-45,'n,partition'); Line(65,GetMaxY-25,65,10); Line(65,GetMaxY-25,GetMaxX-10,GetMaxY-25); Line(GetMaxX-35,GetMaxY-30,GetMaxX-10,GetMaxY-25); Line(GetMaxX-35,GetMaxY-20,GetMaxX-10,GetMaxY-25); Line(60,25,65,10); Line(70,25,65,10); {Насечки на оси Ох} for j:=1 to 6 do begin x1:=trunc(len[j]/(14000/100)); str(len[j]:5:0,sx); OutTextXY(x1+50,GetMaxY-10,sx); end; {Насечки на оси Оу} for u:=1 to 20 do begin x1:=GetMaxY-10-(10000*u div 250); str(0.15*u/4:5:4,sx); OutTextXY(10,x1,sx); end; x1:=12; y1:=812; x2:=12; y2:=812; for j:=1 to 3 do begin {Выбираем точность в зависимости от j} {Это нужно для того, чтобы выводились те же результаты, что и в таблице} case j of 1: l:=4; 2: l:=5; 3: l:=6; end; {Отрисовка значений, полученных методом левых прямоугольников} SetColor(Red); line(x1+50,y1,trunc(NumbPart[i,j]/(14000/600))+50,GetMaxY-25-trunc(results[i,j]) div 250); str(results[i,j]:5:l,sy); x1:=trunc(NumbPart[i,j]/(14000/200))+50; y1:=GetMaxY-25-trunc(results[i,j]) div 250; OutTextXY(x1+50,y1-10,sy); {Отрисовка значений, полученных методом центральных прямоугольников} SetColor(Green); line(x2+50,y2,trunc(NumbPart[i,j+3]/(14000/600))+50,GetMaxY-25-trunc(results[i,j+3]) div 250); str(results[i,j+3]:5:l,sy); x2:=trunc(NumbPart[i,j+3]/(14000/600)); y2:=GetMaxY-25-NumbPart[i,j+3] div 250; OutTextXY(x2+50,y2-20,sy); end; readkey; end; End;