[A, B] – отрезок, на котором задана исходная функция.
Ymax – максимальное значение функции на отрезке.
Ymin – минимальное значение функции на отрезке.
(X_win_min, Y_win_min) – левый верхний угол на экране монитора.
(X_win_max, Y_win_min) – правый верхний угол на экране монитора.
(X_win_min, Y_win_max) – левый нижний угол на экране монитора.
(X_win_max, Y_win_max) – правый нижний угол на экране монитора.
рис. 1.4
Теперь, когда у нас все готово, приведем формулы преобразования точек из обычной системы координат в компьютерную.
В данных формулах (X, Y) – это координаты точки в обычной системе координат, а (Xwin, Ywin) – координаты на экране монитора. Обратите внимание, что формулы не симметричны относительно осей X и Y. Как уже было упомянуто, это связано с тем, что компьютерная система координат устроена так, что ось Y направлена вниз, в то время, как в обычной системе эта ось направлена вверх. Данные формулы универсальны – используя их, можно вписать график любой функции в любой прямоугольник на экране. Тем не менее, все-таки есть очевидные ограничения на их использование. Во-первых, Ymax и Ymin должны достигаться на отрезке [A, B]. Существуют функции, которые не имеют максимума или минимума на заданном отрезке. Например, гипербола y=1/x не имеет ни того, ни другого на отрезке [-1, 1]. Ниже мы разберем как строить графики таких функций. Во-вторых, Ymax и Ymin должны быть различны, иначе в знаменателе мы получим ноль. Этот случай, впрочем, разрешается элементарно. Если у нас Ymax равен Ymin, то мы имеем дело с функцией y=const и в этом случае ее графиком будет просто горизонтальная линия.
Определим две функции, с помощью которых мы будем производить конвертацию.
Сама конвертация выглядит так, как показано на листинге ниже. В данном коде мы воспользовались функционалом, который предоставляет нам System.Linq для поиска минимального и максимального значений в массиве Y, а также для самой конвертации.
В переменных Xwin и Ywin теперь у нас лежит коллекция координат точек, которые мы соединим линией.
Построение графика в полярной системе координат
Для построения графика функции, заданной в полярной системе координат, мы сначала научимся конвертировать значения функции в декартову систему. Итак, пусть есть пара значений в полярной системе координат (r, t), давайте получим для нее соответствие в декартовой системе. Как видно из иллюстрации ниже, координата по оси OX равна произведению длины радиуса вектора r на косинус угла t, а по оси Y, соответственно, это произведение r на синус t.
рис. 1.6
Таким образом получаем: x=r⋅cos (t), y=r⋅sin (t);
Сами формулы перехода достаточно просты. А поскольку мы теперь умеем переводить полярные координаты в декартовы, то можем считать, что мы успешно свели задачу к предыдущей.
Построение графика функции, заданной параметрически
Построение графика такой функции во многом схоже с построением функции, заданной явно. Более того, явное задание функции может быть сведено к параметрическому, а именно:
y = f (x) => X=t, Y=f (t)
Обратное преобразование от параметрического к явному не всегда возможно. В целом, как уже было сказано, построение графика такой функции не несет в себе принципиально иного подхода. Немного изменятся лишь функции конвертации значений из обычной системы в экранную.
Как видим в формуле для X (преобразование по оси Y не претерпело изменений), величины A и B заменены на Xmin и Xmax соответственно.
Выбор N
График может занимать маленькую часть на экране монитора или весь экран, но в любом случае мы хотим чтобы он был гладким и приятным для восприятия. Возникает вопрос: сколько требуется точек, чтобы график выглядел хорошо? Вообще число точек должно быть пропорционально длине графика. Исходя из этого, можно предложить следующий метод. Изначально мы берем довольно много точек в обычной системе координат, например, 10000. Далее конвертируем эти точки в экранную систему, а затем формируем новую коллекцию точек по следующему алгоритму – добавляем первую точку, а следующую точку добавляем с условием, что она отстает от предыдущей не менее, чем на 4 (например) пикселя. Получившуюся коллекцию соединяем линией. При таком подходе мы обеспечиваем приемлемый вид графика вне зависимости от того, сколько места он занимает на экране.