Шрифт:
win.attach(s2);
win.attach(s3);
win.wait_for_button;
Сначала определяем несколько констант, чтобы не перегружать нашу программу “магическими константами”. Затем создаем окно, определяем функции, связываем их с окном и передаем контроль графической системе, которая выполняет реальное рисование на экране.
Все это делается по шаблону, за исключением определений трех объектов класса
Function
: s
, s2
и s3
.
Function s(one,r_min,r_max,orig,n_points,x_scale,y_scale);
Function s2(slope,r_min,r_max,orig,n_points,x_scale,y_scale);
Function s3(square,r_min,r_max,orig,n_points,x_scale,y_scale);
Каждый объект класса
Function
определяет, как их первый аргумент (функция с одним аргументом типа double
, возвращающая значение типа double
) будет нарисован в окне. Второй и третий аргументы задают диапазон изменения переменной x
(аргумента изображаемой функции). Четвертый аргумент (в данном случае orig
) сообщает объекту класса Function
, в каком месте окна расположено начало координат (0,0)
.
Text
(см. раздел 13.11).
Text ts(Point(100,y_orig–40),"one");
Text ts2(Point(100,y_orig+y_orig/2–20),"x/2");
Text ts3(Point(x_orig–100,20),"x*x");
win.set_label("Function graphing: label functions");
win.wait_for_button;
С этого момента на протяжении всей главы мы будем пропускать повторяющийся код, связывающий фигуру с окном, присваивающий ей метку и ожидающий щелчка на кнопке Next.
x/2
касается параболы x*x
в точке (0,0)
, а график функции one пересекает линию x/2
в точке (2,1)
, но это известно лишь нам; для того чтобы это стало очевидно читателям, на рисунке следует нанести оси координат. Код для построения осей состоит из объявлений двух объектов класса
Axis
(раздел 15.4).
const int xlength = xmax–40; // оси должны быть чуть меньше окна
const int ylength = ymax–40;
Axis x(Axis::x,Point(20,y_orig), xlength,
xlength/x_scale, "one notch == 1");
Axis y(Axis::y,Point(x_orig, ylength+20),
ylength, ylength/y_scale, " one notch == 1");
Использование значения
xlength/x_scale
в качестве параметра, задающего количество делений, позволяет использовать целочисленные отметки 1, 2, 3 и т.д. Выбор точки (0,0)
в качестве начала координат является общепринятым. Если хотите, чтобы начало координат было не в центре, а, как обычно, в левом нижнем углу окна (раздел 15.6), вы легко сможете сделать это. Кроме того, для того чтобы различать оси, можно использовать цвет.
x.set_color(Color::red);
y.set_color(Color::red);
Итак, получаем результат, показанный ниже.
15.3. Класс Function
Определение класса графического интерфейса
Function
приведено ниже.
struct Function:Shape {
// параметры функции не хранятся
Function(Fct f,double r1,double r2,Point orig,
int count = 100,double xscale = 25,double yscale = 25);
};
Класс
Function
является производным от класса Shape
. Конструктор класса Function
генерирует множество отрезков линий и хранит их в членах класса Shape
. Эти отрезки линий аппроксимируют значения функции f
. Значения функции f
вычисляются count раз в точках, равномерно распределенных по интервалу [r1:r2]
.