Неправильное вычисление масштабного коэффициента при построении графика - 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
используются для вычисления координат пикселей на экране для каждого шага построения графика.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д