Помощь - Поиск - Пользователи - Календарь
Полная версия: Pascal 7.0 График функции и таблица
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
DarkMoonSide
Дали задание, не когда прежде не работала с графикой, почитала... стало страшно sad.gif дали 4 дня на выполнение работы

Нужно построить график функции y=lg(x)
и рядом с графиком выводилась табличка
что то типа
X|Y
1 3
2 3
1 4
Несколько значений функции в точках smile.gif Как когда то, в школе делали таблички к графикам.
rolleyes.gif
И если не трудно, можно с комментариями, посмотрела что можно с помощью графики делать- понравилось smile.gif
Выручайте
DarkMoonSide
Ув. Оззик smile.gif Вы кинули ссылку на постороение "любого графика функции". У меня не строиться, просто черный екран после компиляции,
можете скинуть код программы? для графика
y=lg(x)... не пойму что не так у меня и вопрос, как мне можно начертить эту злополучную табличку...
volvo
Цитата
y=lg(x)...
Имеется в виду логарифм с основанием 10?
DarkMoonSide
Да, имеется в виду log 10 с основанием 10.
И еще, как сделать рядом с графиком таблицу с некими значениями X и Y...
п.с
mega_chok.gif скоро дадут курсавик, надеюсь там не будет игры... Графику не потяну sad.gif

Ап..
не сплю sad.gif
volvo
Графика - это самое интересное, что только может быть, ты просто еще не втянулась в процесс 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
Спасибо огромное, и еще пару вопросов, а то интересненькое 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
Это не одна, а две функции... Первая - f - считает заданную тобой функцию, f = lg(x), поскольку готовой функции для вычисления десятичных логарифмов в паскале нет - приходится переходить к другому основанию, к тому, которое есть. А есть ln - натуральный логарифм. По формуле получаем log10X = logeX / loge10... И записываем это в виде функции.

А вторая - это просто "обертка" над процедурой Str, которая переводит число в строку. Можно было и без нее обойтись, но тогда пришлось бы каждый раз перед выводом значений X и Y дважды вызывать процедуру Str, да еще и 2 дополнительных переменных (ну, одна в лучшем случае). А так все преобразование обоих значений - в одной строке кода...
DarkMoonSide
Такс, все заработало, это теперь мне, что бы над графиком функции было написано
ГРАФИК ФУНКЦИИ y=lg(x) и возле осей были X Y
писать с помощью команды outtextxy(координата х, координата у, текст) ?
volvo
Отображается... Только для этого забери из папки BGI (ну, или где он там у тебя находится, по-моему все-таки в BGI) файл LITT.CHR и скопируй (не надо перемещать, именно скопируй) его в ту же папку, где лежит программа. Тогда шрифт изменится на SmallFont, длина выводимых строк уменьшится, и строки будут отображаться. А сейчас длина строки большая, ее левый край выходит за пределы экрана, и поэтому строки не отображаются.
DarkMoonSide
Спасибо, уже додумалась 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
Цитата
Где в коде находиться значиние в таблице, и строиться сама таблица <...>
А где рисуется сам график, и оси координат?
Вот в том фрагменте, что ты привела, все, что между If ... Begin и End - это вывод очередной строки таблицы. А график - это PutPixel. Причем заметь, все точки, для которых в таблице присутствует значение, выделены на графике красным цветом. Нашла, где изменяется цвет вывода точки?

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

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

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

Добавлено через 1 мин.
Цитата
как можно сделать, допустим что бы значение X нужно было вводить с клавиатуры?
Вводить строку в графическом режиме, посимвольно... И это я выкладывал, ищи...
DarkMoonSide
Угу, разобралась с цветовой гаммой, как делать линии, не множко не поняла как ты сделал отсчет, точнее откуда...
(я брюнетка!!! blum.gif rolleyes.gif )
Та мне не обязательно рус шрифт, и транслит пойдет, просто через аутттекст вводить ?smile.gif
п.с. личку прочитай пожалуйсто, если время будет, напишеш ?smile.gif
volvo
Цитата
просто через аутттекст вводить ?
Через OutText ничего нельзя вводить, можно только ВЫводить smile.gif Да, выводится строка через OutText/OutTextXY. А вводить строку в граф. режиме можно вот так: Графика
DarkMoonSide
Cпасибо, пашла читать smile.gif
п.с. если не трудно и будет время, хочу понять полностью программку...
сможеш написать коментарии к строкам в программе? где идет точный ввод графика, где расчет пикселей, и как сделано что точка из таблицы-красный цвет в графике

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

Добавлено через 15 мин.
blink.gif что то не могу поймать координаты, криво пишет smile.gif))
п.с. ап если времячко будет smile.gif что бы если что, сама смогла подобную написать
DarkMoonSide
Я знаю, я в край обнаглела, но я поспрашиваю вопросы по программе... потому что интересно, и здать ее тоже нужно будет 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
rolleyes.gif
volvo
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
Cпасибо всем огромное smile.gif smile.gif
еще пару вопросиков будет smile.gif но в другой темке.
еще раз спс, пошла учить )
DarkMoonSide
все поняла, разобралась smile.gif "Дорисовала" надписи smile.gif))
но можешь объяснить подробно
outtextxy(TableWidth div 2, ((n div 10) + 2) * (textheight('W') + 3),
RealToStr(X) + ' ' + RealToStr(Y));
что тут? и что значит 'W' ?
Ozzя
textheight('W') - просто взяли самую широкую букву и рассчитываем координаты от ее ширины.
RealToStr(X) - переводим число в строку, т.к. outTextXY не умеет работать с числами, а только со строками
volvo
Высоту, Оззя... Я не написал TextWidth, я написал TextHeight. На что мне во втором параметре OutTextXY нужна ширина буквы? Мне нужна высота, чтобы следующую строку напечатать там, где была предыдущая + высота буквы при выбранном шрифте + еще 3 пикселя промежутка...
Ozzя
volvo
Ну да, ашыпко rolleyes.gif
Пальцы раньше мысли стали работать... mega_chok.gif
Годы не те уже nea.gif
kpoxa
ребят,простите пожалуйста.зашла вот на ваш форум))) меня заинтересовала задача с построением графика десятичного логарифма,перепечатала ее,но к сожалению у меня выдает ошибку((( пишет error while linking. не могли бы подсказать,что это значит и как это исправить...может это из-за того что у меня free а не turbo pascal?очень надеюсь на вашу помощь!заранее огромное спасибо
volvo
Если ты о программе из поста №6, то она и отлаживалась на FPC, так что все прекрасно работает. Включи отображение всех хинтов, предупреждений и замечаний, как описывается здесь, перекомпилируй программу, и показывай полный листинг, что у тебя выводится в окне Compiler Messages... (чтобы показать это окно - надо нажать F12)

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