Неправильное вычисление масштабного коэффициента при построении графика - Turbo Pascal

Узнай цену своей работы

Формулировка задачи:

В большинстве примеров построения графиков масштабный коэффициент вычисляют по формуле ky=height/abs(y_max-y_min). Что эта формула не подходит для случаев когда y_min и y_max не симметричны относительно оси абсцисс можно убедиться на примере. w = 400, h = 640 a = - 5, b = 5 f(x) = x + 2 X0 = 200, Y0 = 320 y_min = -3, y_max = 7 kx = 400/(5 + 5) = 40 ky = 640/(3 + 7) = 64 Формулы для экранных координат: X = X0 + x·kx Y = Y0 + y·ky Получаем: X_min = 200 + 40·(-5) = 0 X_max = 200 + 40·5 = 400 Y_min = 320 - 64·(-3) = 512 Y_max = 320 - 64·7 = -128 Очевидно, что последние значения неправильны. Если вычислить ky «по бумажке», Y_min = 440 Y_max = 40, то имеем ky = 400/10 = 40 Тогда и график строится правильно. Пример неправильного и правильного (зелёный) графиков. Но вот вопрос: как узнать правильный коэффициент???

Решение задачи: «Неправильное вычисление масштабного коэффициента при построении графика»

textual
Листинг программы
{программа построения дух графиков на одной оси координат}
program P;
 
uses
  Graph,
  WinCRT;
 
  function f1(X: real): real;
  begin
    f1 := 16 * sqr(X);
  end;
 
  function f2(X: real): real;
  begin
    f2 := 1 / 7 * sqr(X);
  end;
 
var
  GraphDevice, GraphMode: integer;
  ScreenXstart, ScreenXfinish, ScreenYstart, ScreenYfinish: integer;
  ScaleX, ScaleY: real;
  Xstart, Xfinish, Ystart, Yfinish: real;
  X, Y, dX: real;
  Xscreen, Yscreen: integer;
  IsNextVisiblePixel: boolean;
begin
  {параметры графиков}
  Xstart  := -0.05;
  Xfinish := 0.05;
  Ystart  := 0.0;
  Yfinish := 0.0010;
  {инициализация графики}
  GraphDevice := Detect;
  GraphMode := Detect;
  InitGraph(GraphDevice, GraphMode, '');
  if GraphResult <> grOk then
  begin
    writeln('Error');
    Exit;
  end;
  {от края экрана отступим по 10% экрана}
  ScreenXstart := GetMaxX div 10;
  ScreenXfinish := GetMaxX - ScreenXstart;
  ScreenYstart := GetMaxY div 10;
  ScreenYfinish := GetMaxY - ScreenYstart;
  {расчёт масштабных коэффициентов}
  ScaleX := (ScreenXfinish - ScreenXstart) / (Xfinish - Xstart);
  ScaleY := (ScreenYfinish - ScreenYstart) / (Yfinish - Ystart);
  {построение осей координат}
  SetColor(7);
  MoveTo(ScreenXstart, ScreenYstart);
  LineTo(ScreenXstart, ScreenYfinish);
  LineTo(ScreenXfinish, ScreenYfinish);
  LineTo(ScreenXfinish, ScreenYstart);
  LineTo(ScreenXstart, ScreenYstart);
 
  MoveTo((ScreenXfinish + ScreenXstart) div 2, ScreenYstart);
  LineTo((ScreenXfinish + ScreenXstart) div 2, ScreenYfinish);
  {построение 1-го графика}
  SetColor(5);
  IsNextVisiblePixel := False;
  X  := Xstart;
  dX := (Xfinish - Xstart) / 1000;
  while X <= Xfinish do
  begin
    Y := f1(X);
    Xscreen := round((X - Xstart) * ScaleX) + ScreenXstart;
    Yscreen := -round((Y - Ystart) * ScaleY) + ScreenYfinish;
    if (Xscreen >= ScreenXstart) and (Xscreen <= ScreenXfinish) and
      (Yscreen > ScreenYstart) and (Yscreen < ScreenYfinish) then
    begin
      if IsNextVisiblePixel then
        LineTo(Xscreen, Yscreen)
      else
        MoveTo(Xscreen, Yscreen);
      IsNextVisiblePixel := True;
    end
    else
      IsNextVisiblePixel := False;
    X := X + dX;
  end;
  {построение 2-го графика}
  SetColor(4);
  IsNextVisiblePixel := False;
  X  := Xstart;
  dX := (Xfinish - Xstart) / 1000;
  while X <= Xfinish do
  begin
    Y := f2(X);
    Xscreen := round((X - Xstart) * ScaleX) + ScreenXstart;
    Yscreen := -round((Y - Ystart) * ScaleY) + ScreenYfinish;
    if (Xscreen >= ScreenXstart) and (Xscreen <= ScreenXfinish) and
      (Yscreen > ScreenYstart) and (Yscreen < ScreenYfinish) then
    begin
      if IsNextVisiblePixel then
        LineTo(Xscreen, Yscreen)
      else
        MoveTo(Xscreen, Yscreen);
      IsNextVisiblePixel := True;
    end
    else
      IsNextVisiblePixel := False;
    X := X + dX;
  end;
  ReadKey;
end.

Объяснение кода листинга программы

  1. В функции f1 коэффициент масштабирования 16 умножается на квадрат аргумента X.
  2. В функции f2 коэффициент масштабирования 1/7 умножается на квадрат аргумента X.
  3. Переменные GraphDevice, GraphMode инициализируются функцией Detect, которая возвращает детектированный устройство для графика.
  4. Переменные ScreenXstart, ScreenXfinish, ScreenYstart и ScreenYfinish вычисляются как 10% от максимальных значений X и Y.
  5. Коэффициенты масштабирования ScaleX и ScaleY вычисляются как отношение максимальных значений ScreenX и ScreenY к максимальным значениям X и Y.
  6. Оси координат строятся с помощью функции MoveTo и LineTo.
  7. Первый график строится с помощью функции f1.
  8. Второй график строится с помощью функции f2.
  9. Переменная IsNextVisiblePixel используется для отслеживания следующего видимого пикселя при построении графика.
  10. Переменные X, Y и dX используются для вычисления текущего положения X и Y и изменения их значения на единицу dX при каждом шаге построения графика.
  11. Переменные Xscreen и Yscreen используются для вычисления координат пикселей на экране для каждого шага построения графика.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

15   голосов , оценка 4 из 5
Похожие ответы