Неправильное вычисление масштабного коэффициента при построении графика - 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.
Объяснение кода листинга программы
- В функции
f1
коэффициент масштабирования16
умножается на квадрат аргументаX
. - В функции
f2
коэффициент масштабирования1/7
умножается на квадрат аргументаX
. - Переменные
GraphDevice
,GraphMode
инициализируются функциейDetect
, которая возвращает детектированный устройство для графика. - Переменные
ScreenXstart
,ScreenXfinish
,ScreenYstart
иScreenYfinish
вычисляются как 10% от максимальных значенийX
иY
. - Коэффициенты масштабирования
ScaleX
иScaleY
вычисляются как отношение максимальных значенийScreenX
иScreenY
к максимальным значениямX
иY
. - Оси координат строятся с помощью функции
MoveTo
иLineTo
. - Первый график строится с помощью функции
f1
. - Второй график строится с помощью функции
f2
. - Переменная
IsNextVisiblePixel
используется для отслеживания следующего видимого пикселя при построении графика. - Переменные
X
,Y
иdX
используются для вычисления текущего положенияX
иY
и изменения их значения на единицуdX
при каждом шаге построения графика. - Переменные
Xscreen
иYscreen
используются для вычисления координат пикселей на экране для каждого шага построения графика.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д