IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

> Рисование графика, Проблемы с выводом графика
сообщение
Сообщение #1


Пионер
**

Группа: Пользователи
Сообщений: 64
Пол: Мужской

Репутация: -  0  +


Довольно долго помучавшись с интегралами, решил прикрутить к проге отрисовку графика, который будет рисовать на основе данных, берущихся из двух массивов, одна возникла неприятность:
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;

Var
results : res;
NumbPart : part;
XY : integer;
f : func;
left,right : double;
i,j,k : byte;
methodRes : res;

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;

{Основная программа}
Begin
clrscr;
{рисуем таблицу}
DrawTable;
{рисуем график}
DrawGraph;
readkey;
End.


Сообщение отредактировано: Relrin -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
сообщение
Сообщение #2


Гость






Значит, смотри, что у меня получилось...

Во-первых, я не мог оставить эти "магические числа", кое-что я поправил, добавил символические константы, чтоб было понятно, что и как. Изменил стиль вывода строк, опять же, чтобы уйти от "магии" я использовал SetTextJustify для выравнивания текста, ну, увидишь... Чтобы была возможность обрабатывать значение "2" в NumbPart, массив Len начинается с 2-х, то есть, я увеличил его размер на 1, и сделал индексы тоже константами, теперь можно добавить еще значения, и подкорректировать Last, и все будет работать корректно, не надо будет ползать по всей программе и искать, "А где ж еще там у меня надо изменить 6 на 7?"

А, еще добавил что-то вроде грида на график, так смотрится лучше, чем просто пустой экран...

В общем, запустил, получил что-то похожее на то, что ты нарисовал, только перепады маленькие, получается в большинстве своем ровная линия, надо будет, наверное, изменить шаг по OY... Но это уже сам, у меня сейчас аврал начинается... sad.gif


Прикрепленные файлы
Прикрепленный файл  relrin.pas ( 6.81 килобайт ) Кол-во скачиваний: 366
 К началу страницы 
+ Ответить 

Сообщений в этой теме


 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 9.09.2025 12:10
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name