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

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

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

> Рисование графика, Проблемы с выводом графика
Relrin
сообщение 20.03.2011 16:07
Сообщение #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 - 20.03.2011 16:19
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
Relrin
сообщение 21.03.2011 7:55
Сообщение #2


Пионер
**

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

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


Цитата(volvo @ 21.03.2011 0:24) *

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

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

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

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

Спасибо, работает. Дальше сам буду good.gif
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

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


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

 



- Текстовая версия 20.07.2025 18:32
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"