Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ Pascal 7.0 График функции и таблица

Автор: DarkMoonSide 12.02.2009 6:45

Дали задание, не когда прежде не работала с графикой, почитала... стало страшно sad.gif дали 4 дня на выполнение работы

Нужно построить график функции y=lg(x)
и рядом с графиком выводилась табличка
что то типа
X|Y
1 3
2 3
1 4
Несколько значений функции в точках smile.gif Как когда то, в школе делали таблички к графикам.
rolleyes.gif
И если не трудно, можно с комментариями, посмотрела что можно с помощью графики делать- понравилось smile.gif
Выручайте

Автор: Ozzя 12.02.2009 10:59

http://forum.pascal.net.ru/index.php?s=&showtopic=2729&view=findpost&p=23770

Автор: DarkMoonSide 13.02.2009 1:31

Ув. Оззик smile.gif Вы кинули ссылку на постороение "любого графика функции". У меня не строиться, просто черный екран после компиляции,
можете скинуть код программы? для графика
y=lg(x)... не пойму что не так у меня и вопрос, как мне можно начертить эту злополучную табличку...

Автор: volvo 13.02.2009 1:53

Цитата
y=lg(x)...
Имеется в виду логарифм с основанием 10?

Автор: DarkMoonSide 13.02.2009 2:00

Да, имеется в виду log 10 с основанием 10.
И еще, как сделать рядом с графиком таблицу с некими значениями X и Y...
п.с
mega_chok.gif скоро дадут курсавик, надеюсь там не будет игры... Графику не потяну sad.gif

Ап..
не сплю sad.gif

Автор: volvo 13.02.2009 2:41

Графика - это самое интересное, что только может быть, ты просто еще не втянулась в процесс smile.gif Смотри:

uses graph;
{ Ну, назначение этих двух функций я уже объяснял, поэтому вкратце: }

{ 1) вычисление log10(x)
поскольку библиотечной функции нет - пришлось написать свою }
function f(X: real): real;
begin
f := ln(X) / ln(10);
end;

{ 2) Перевод вещественного числа в строку с точностью 3 знака после запятой,
только для более удобного использования, чем непосредственный вызов Str }
function RealToStr(X: real): string;
var st: string;
begin
str(X:6:3, st);
RealToStr := st;
end;

{ Это - для масштабирования
ScaleX определяет, насколько будет "вытянут" график по оси OX, а
ScaleY - насколько он будет вытянут по оси OY.

При увеличении соответствующего значения расстояние между координатами точек
на графике будет больше, и график будет более "разреженным", при уменьшении - наоборот,
график "уплотнится", поскольку расстояние между координатами точек уменьшится }
const
ScaleX = 20;
ScaleY = 60;

{ Ну, тут не будем останавливаться надолго, переменные они и есть переменные, их
назначение я опишу при использовании }
var
TableWidth, CenterX, CenterY: integer;
gDriver, gMode, errCode: integer;
color, n: integer;
X, Y: real;

begin
{ Поехали! Прежде всего инициализируем графику }
gDriver := Detect;
InitGraph(gDriver, gMode, '');
{ Получаем результат инициализации (была ли ошибка?) }
errCode := graphresult;
if errCode <> grOk then begin
{ Если не grOk - значит, была ошибка, выводим ее описание,
и выходим из программы Halt-ом, 100 - это код завершения,
который вернет программа. Можешь вернуть любое число 0 .. 65536,
но обычно 0 - это корректное завершение программы, а тут - ошибка...
Я привык возвращать 100 при ошибках инициализации графики... }
writeln('ERROR: ' + grapherrormsg(errCode));
readln; halt(100)
end;

{ Теперь определяем, какой ширины будет таблица. Чтоб не привязываться
к конкретным значениям (ну вот у тебя ширина экрана = 640, а у меня = 800),
ширину таблищы вычисляем в зависимости от ширины экрана: 1/6 ширины
займет таблица, все остальное - график }
TableWidth := getmaxx div 6;

{ Вот это - точка начала координат для моего графика.
По OX - небольшой отступ от "области таблицы", по OY - середина экрана }
CenterX := TableWidth + 10;
CenterY := getmaxy div 2;

{ Рисуем координатные оси... Пускай они будут зелеными... }
setcolor(lightgreen);
line(CenterX, CenterY, getmaxx - 10, CenterY);
line(CenterX, 10, CenterX, getmaxy - 10);

{ Начальное значение X }
X := 0.1;
n := 0; { Это - количество точек, которые уже были добавлены к графику }

{ Теперь настроим шрифт.
Во-первых, его цвет будет белым,
Во-вторых, сам шрифт будет LITT.CHR (smallfont определяет именно этот шрифт),
чтоб координаты точек помещались в таблицу, и горизонтально-ориентированным
(horizdir). Двойка - это размер самого шрифта. То есть, он как бы не совсем маленький,
при 1 он будет еще меньше...
Третье: настраиваем вывод текста (settextjustify): эта процедура определяет, где именно
будет выводиться текст после вызова OutTextXY, что определяют координаты, в которых
текст выводится... В моем случае координаты определяют ЦЕНТР текста. То есть, текст
выведется так, что его середина (и по OX, и по OY) совпадет с заданными координатами.
Именно середина, не левый, и не правый край, не верх и не низ !!!}
setcolor(white);
settextstyle(smallfont, horizdir, 2);
settextjustify(centertext, centertext);

{ Выводим заголовок таблицы }
outtextxy(TableWidth div 2, textheight('W') + 3,
'X | Y');

{ Теперь для всех X-ов, от начального значения, пока X будет < 20, делаем следующее: }
while X < 20 do begin
Y := f(X); { Вычисляем значение функции }

if n mod 10 = 0 then begin
{ Для каждой десятой точки печатаем ее координаты в таблицу, а саму точку будем
выводить красным цветом на графике }
color := lightred;
outtextxy(TableWidth div 2, ((n div 10) + 2) * (textheight('W') + 3),
RealToStr(X) + ' ' + RealToStr(Y));
end
else color := white; { если эта точка НЕ каждая десятая - то просто выведем ее белой... }

{ Собственно, сам вывод точки на график: задаем смещение от начала координат:
по оси OX это значение X, отмасштабированное с помощью ScaleX
по оси OY - значение Y, опять же отмасштабированное ScaleY, но поскольку система
координат модуля graph такая, что координата Y увеличивается СВЕРХУ ВНИЗ, то приходится
отнимать, а не прибавлять полученное смещение от CenterY, чтобы график выглядел так, как
привыкли мы, а не так, как привык Borland... }

putpixel(CenterX + trunc(X * ScaleX),
CenterY - trunc(Y * ScaleY), color);

{ Ну все, дальше уже мелочи, увеличиваем значение X, увеличиваем число точек,
отображенных на графике }
X := X + 0.2;
inc(n)
end;
{ график начерчен, ждем реакции пользователя }
readln;
{ и выходим... Не забываем закрыть граф. режим }
closegraph;
end.

rolleyes.gif

Автор: DarkMoonSide 13.02.2009 2:54

Спасибо огромное, и еще пару вопросов, а то интересненькое smile.gif)
Что делает эта функция?
function f(X: real): real;
begin
f := ln(X) / ln(10);
end;
function RealToStr(X: real): string;
var st: string;
begin
str(X:6:3, st);
RealToStr := st;
end;

точнее переводит тип реал, но для чего ?smile.gif можно кратенькую теорию, если есть время

Автор: volvo 13.02.2009 3:03

Это не одна, а две функции... Первая - f - считает заданную тобой функцию, f = lg(x), поскольку готовой функции для вычисления десятичных логарифмов в паскале нет - приходится переходить к другому основанию, к тому, которое есть. А есть ln - натуральный логарифм. По формуле получаем log10X = logeX / loge10... И записываем это в виде функции.

А вторая - это просто "обертка" над процедурой Str, которая переводит число в строку. Можно было и без нее обойтись, но тогда пришлось бы каждый раз перед выводом значений X и Y дважды вызывать процедуру Str, да еще и 2 дополнительных переменных (ну, одна в лучшем случае). А так все преобразование обоих значений - в одной строке кода...

Автор: DarkMoonSide 13.02.2009 3:04

Такс, все заработало, это теперь мне, что бы над графиком функции было написано
ГРАФИК ФУНКЦИИ y=lg(x) и возле осей были X Y
писать с помощью команды outtextxy(координата х, координата у, текст) ?

Автор: volvo 13.02.2009 3:08

Отображается... Только для этого забери из папки BGI (ну, или где он там у тебя находится, по-моему все-таки в BGI) файл LITT.CHR и скопируй (не надо перемещать, именно скопируй) его в ту же папку, где лежит программа. Тогда шрифт изменится на SmallFont, длина выводимых строк уменьшится, и строки будут отображаться. А сейчас длина строки большая, ее левый край выходит за пределы экрана, и поэтому строки не отображаются.

Автор: DarkMoonSide 13.02.2009 3:12

Спасибо, уже додумалась smile.gif)
Осталось вывести над графиком пару строк, и оси сделать smile.gif
И еще вопрос...
спросила двух знакомых, один говорит отсчет координат справа сверху, другой слева...

Добавлено через 7 мин.
Такс, извените smile.gif еще пару вопросов по программе.
Где в коде находиться значиние в таблице, и строиться сама таблица

while X < 20 do begin
Y := f(X);
if n mod 10 = 0 then begin
color := lightred;
outtextxy(TableWidth div 2, ((n div 10) + 2) * (textheight('W') + 3),
RealToStr(X) + ' ' + RealToStr(Y));
end
else color := white;

putpixel(CenterX + trunc(X * ScaleX),
CenterY - trunc(Y * ScaleY), color);
X := X + 0.2;
inc(n)
end;

я правильно поняла?

А где рисуется сам график, и оси координат?

Процедуру для ошибки тоже уже выучила smile.gif))


Добавлено через 18 мин.
Такс, и еще вопрос, так, как модуль сrt не подключен, как можно сделать, допустим что бы значение X нужно было вводить с клавиатуры?
(я про y=lg(x)) Для себя просто интересно

Автор: volvo 13.02.2009 3:50

Цитата
Где в коде находиться значиние в таблице, и строиться сама таблица <...>
А где рисуется сам график, и оси координат?
Вот в том фрагменте, что ты привела, все, что между If ... Begin и End - это вывод очередной строки таблицы. А график - это PutPixel. Причем заметь, все точки, для которых в таблице присутствует значение, выделены на графике красным цветом. Нашла, где изменяется цвет вывода точки?

А оси координат - это два Line-а, из всего 2 в программе, так что ошибиться невозможно smile.gif

Цитата
спросила двух знакомых, один говорит отсчет координат справа сверху, другой слева...
Это ты о чем? В Паскале принято, что левый верхний угол имеет координату 0, 0 и координата Y увеличивается вниз, а координата X увеличивается вправо. Но тебе это зачем в данном случае? В МОЕЙ программе от точки пересечения координатных осей вверх - это ось OY, а вправо - это ось OX...

Цитата
что бы над графиком функции было написано
ГРАФИК ФУНКЦИИ y=lg(x) и возле осей были X Y
А вот тут и начинаются проблемы. Тебе нужны русифицированные шрифты, где-то на форуме я уже выкладывал на них ссылку, попробуй поискать, стандартные шрифты по-русски не пишут... Как найду - напишу, где именно качать их...

Добавлено через 1 мин.
Цитата
как можно сделать, допустим что бы значение X нужно было вводить с клавиатуры?
Вводить строку в графическом режиме, посимвольно... И это я выкладывал, ищи...

Автор: DarkMoonSide 13.02.2009 3:54

Угу, разобралась с цветовой гаммой, как делать линии, не множко не поняла как ты сделал отсчет, точнее откуда...
(я брюнетка!!! blum.gif rolleyes.gif )
Та мне не обязательно рус шрифт, и транслит пойдет, просто через аутттекст вводить ?smile.gif
п.с. личку прочитай пожалуйсто, если время будет, напишеш ?smile.gif

Автор: volvo 13.02.2009 4:05

Цитата
просто через аутттекст вводить ?
Через OutText ничего нельзя вводить, можно только ВЫводить smile.gif Да, выводится строка через OutText/OutTextXY. А вводить строку в граф. режиме можно вот так: http://forum.pascal.net.ru/index.php?s=&showtopic=13890&view=findpost&p=80759

Автор: DarkMoonSide 13.02.2009 4:15

Cпасибо, пашла читать smile.gif
п.с. если не трудно и будет время, хочу понять полностью программку...
сможеш написать коментарии к строкам в программе? где идет точный ввод графика, где расчет пикселей, и как сделано что точка из таблицы-красный цвет в графике

Добавлено через 3 мин.
Чуть не забыла *blush*
Как высчитываеться X и Y ?
по какому значинию x функция работает? (y=lg(x))

Добавлено через 15 мин.
blink.gif что то не могу поймать координаты, криво пишет smile.gif))
п.с. ап если времячко будет smile.gif что бы если что, сама смогла подобную написать

Автор: DarkMoonSide 13.02.2009 4:59

Я знаю, я в край обнаглела, но я поспрашиваю вопросы по программе... потому что интересно, и здать ее тоже нужно будет smile.gif


const
ScaleX = 20;
ScaleY = 60;


Это мы забиваем в константу что?

halt(100)

Что это? smile.gif

TableWidth := getmaxx div 6;
CenterX := TableWidth + 10;
CenterY := getmaxy div 2;


Что есть TableWidth и что мы добовляем в центр?


while X < 20 do begin
Y := f(X);
if n mod 10 = 0 then begin
color := lightred;
outtextxy(TableWidth div 2, ((n div 10) + 2) * (textheight('W') + 3),
RealToStr(X) + ' ' + RealToStr(Y));
end
else color := white;

putpixel(CenterX + trunc(X * ScaleX),
CenterY - trunc(Y * ScaleY), color);
X := X + 0.2;
inc(n)
end;


Тут происходит что ?smile.gif

line(CenterX, CenterY, getmaxx - 10, CenterY);
line(CenterX, 10, CenterX, getmaxy - 10);


Идет прорисовка осей.
Но как можно еще добавить линии, как-то координатами.
Как удобней ставить текст по координатам, допустим мне в конец осей нужно дописать X и Y?
Прочитала о том, что можно из конечной точки сделать линию дальше.

line(CenterX, CenterY, getmaxx - 10, CenterY);
line(CenterX, 10, CenterX, getmaxy - 10);

Вот функции построения осей координат? как можно добавить что бы график был со стрелочками, точнее как сделать так, что бы из конца линии, были 2 линии по диагонале, как > или < smile.gif
Спасибо огромное за помощь.

Автор: DarkMoonSide 13.02.2009 15:06

rolleyes.gif

Автор: volvo 13.02.2009 15:14

1) комментарии в основную программу добавлены...
2)

Цитата
Вот функции построения осей координат? как можно добавить что бы график был со стрелочками, точнее как сделать так, что бы из конца линии, были 2 линии по диагонале, как > или <
Чуть-чуть изменить код... Я не стал править первоначальный вариант, напишу здесь:

Было:
  setcolor(lightgreen);
line(CenterX, CenterY, getmaxx - 10, CenterY);
line(CenterX, 10, CenterX, getmaxy - 10);

стало:
  setcolor(lightgreen);
line(CenterX, CenterY, getmaxx - 10, CenterY);
{ здесь все просто: точка, к которой надо "прилепить" стрелочку - это (getmaxx-10, centery).
устанавливаем граф. курсор в нее (moveto), и с помощью linerel чертим линию относительно
этой точки на 5 пикселей левее и на 2 выше. А потом - то же самое, но ниже оси координат...
Со второй стрелкой - по аналогии }
moveto(getmaxx - 10, CenterY); linerel(-5, 2);
moveto(getmaxx - 10, CenterY); linerel(-5, -2);

line(CenterX, 10, CenterX, getmaxy - 10);
moveto(CenterX, 10); linerel( 2, 5);
moveto(CenterX, 10); linerel(-2, 5);

, и чуть ниже, было:
  outtextxy(TableWidth div 2, textheight('W') + 3,
'X | Y');

стало:
  outtextxy(TableWidth div 2, textheight('W') + 3,
'X | Y');
{ переходим чуть ниже точки, в которую указывает стрелка OX, и печатаем там название оси }
outtextxy(getmaxx - 10, CenterY + 15, 'X');
{ переходим чуть правее точки, в которую указывает стрелка OY, и печатаем название }
outtextxy(CenterX + 15, 10, 'Y');


Цитата
что то не могу поймать координаты, криво пишет
Это ты о чем? Все нормально по-моему:
Прикрепленное изображение
smile.gif

Автор: DarkMoonSide 14.02.2009 6:16

Cпасибо всем огромное smile.gif smile.gif
еще пару вопросиков будет smile.gif но в другой темке.
еще раз спс, пошла учить )

Автор: DarkMoonSide 14.02.2009 8:40

все поняла, разобралась smile.gif "Дорисовала" надписи smile.gif))
но можешь объяснить подробно
outtextxy(TableWidth div 2, ((n div 10) + 2) * (textheight('W') + 3),
RealToStr(X) + ' ' + RealToStr(Y));
что тут? и что значит 'W' ?

Автор: Ozzя 14.02.2009 11:27

textheight('W') - просто взяли самую широкую букву и рассчитываем координаты от ее ширины.
RealToStr(X) - переводим число в строку, т.к. outTextXY не умеет работать с числами, а только со строками

Автор: volvo 14.02.2009 15:24

Высоту, Оззя... Я не написал TextWidth, я написал TextHeight. На что мне во втором параметре OutTextXY нужна ширина буквы? Мне нужна высота, чтобы следующую строку напечатать там, где была предыдущая + высота буквы при выбранном шрифте + еще 3 пикселя промежутка...

Автор: Ozzя 14.02.2009 15:53

volvo
Ну да, ашыпко rolleyes.gif
Пальцы раньше мысли стали работать... mega_chok.gif
Годы не те уже nea.gif

Автор: kpoxa 5.04.2009 23:43

ребят,простите пожалуйста.зашла вот на ваш форум))) меня заинтересовала задача с построением графика десятичного логарифма,перепечатала ее,но к сожалению у меня выдает ошибку((( пишет error while linking. не могли бы подсказать,что это значит и как это исправить...может это из-за того что у меня free а не turbo pascal?очень надеюсь на вашу помощь!заранее огромное спасибо

Автор: volvo 6.04.2009 0:26

Если ты о программе из поста №6, то она и отлаживалась на FPC, так что все прекрасно работает. Включи отображение всех хинтов, предупреждений и замечаний, как описывается http://forum.pascal.net.ru/index.php?s=&showtopic=16732&view=findpost&p=97982, перекомпилируй программу, и показывай полный листинг, что у тебя выводится в окне Compiler Messages... (чтобы показать это окно - надо нажать F12)

Кстати, убедись, что программа компилируется в режиме совместимости с Турбо-Паскалем: самой первой строкой добавь {$mode tp} или Options -> Compiler -> Syntax в списке справа выбери Turbo Pascal Compatible, и нажми "Ok"...