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 6 do
begin
x1:=trunc(len[j]/(14000/100));
str(len[j]:5:0,sx);
OutTextXY(x1+50,GetMaxY-10,sx);
end;
Что за магические числа 14000 и 100? Почему именно они? Попробовал вывести X1 на консоль перед тем, как использовать в качестве координат:

    for j:=1 to 6 do
begin
writeln('TEST : j = ', j:2, ', val = ', trunc(len[j]/(14000/100)));
x1:=trunc(len[j]/(14000/100));
str(len[j]:5:0,sx);
OutTextXY(x1+50,GetMaxY-10,sx);
end;
, получил
TEST : j =  1, val = 0
TEST : j = 2, val = 0
TEST : j = 3, val = 0
TEST : j = 4, val = 3
TEST : j = 5, val = 14
TEST : j = 6, val = 936
TEST : j = 1, val = 0
TEST : j = 2, val = 0
TEST : j = 3, val = 0
TEST : j = 4, val = 3
TEST : j = 5, val = 14
TEST : j = 6, val = 936

, вот именно так они и выводятся, 4 первых значения сливаются одно с другим, а остальные, вероятно, выходят за пределы отображаемой области (у меня разрешение выставлено в 1920*1024, рисунок выглядит так:
Прикрепленное изображение
, т.е., есть еще и в середине отображение. Но при стандартном 640*480 его не будет видно)... Объясни, что хотелось получить - поможем исправить, чтоб было как нужно.
 К началу страницы 
+ Ответить 

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


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

 





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