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


Гость






Нет. Разобраться в этом нагромождении кода - это выше моих сил. Рассказывай, что это:

Цитата

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;
? Что хранится в NumbPart, и для значений NumbPart, которые получаются ({2048, 16384, 131072, 2, 8, 32}, {16, 64, 512, 8, 32, 64}) нарисуй и покажи график, который должен получиться (хочешь - на листе бумаги + сканнер, хочешь - в Paint-е, но чтоб было видно, что по какой оси должно откладываться, и что с чем - соединяться. И почему вообще минимальное значение в NumbPart = 2, в то время, как отображается на координатной сетке Lenmin = 8).

Я вообще перестал понимать, чего ты хочешь. Эти вот деления в одном случае на (14000/200), а тут же, на том же графике, рядом - с какого-то перепуга уже на (14000/600) не способствуют пониманию происходящего. С чего масштаб-то разный? Ты, извини, значения под осью OX что, разные выводил? Нет, у тебя была одна шкала. Вот и работай ВСЕГДА в этой шкале! Было в "Насечках над осью OX" вычисление trunc(len[ j ]/(14000/100)) - значит больше чем 100 в знаменателе не должно появляться вообще... А если нужно несколько разномасштабных графиков - рисуй несколько осей OX одну над другой, и под каждой - свою шкалу, а над каждой - свой график, тогда будет более понятно, что происходит. А путать все в одну кучу - не надо...
 К началу страницы 
+ Ответить 

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


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

 





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