Печатать книгуПечатать книгу

§ 15. Построение графиков функций и диаграмм

Сайт: Профильное обучение
Курс: Информатика. 11 класс (Повышенный уровень)
Книга: § 15. Построение графиков функций и диаграмм
Напечатано:: Гость
Дата: Суббота, 4 Май 2024, 13:22

15.1. Построение графиков функций

Пример 15.1. Создать проект, в котором следует построить график функции y = x sinx на промежутке, заданном пользователем.

Этапы выполнения задания

  1. Поместить на форму компоненты: Image, два компонента LabeledEdit и компонент Button.
  2. Изменить свойства Caption у компонентов LabeledEdit1, LabeledEdit2 на x0 и xn соответственно.
  3. Изменить свойства Text у компонентов LabeledEdit1 и LabeledEdit2 на -10 и 10 соответственно.
  4. Изменить свойства Caption у компонента Button1 на «Построить график».
  5. Установить размеры Image — 500 × 500.
  6. Написать обработчик события OnClick для компонента Button1, в котором график функции необходимо строить по точкам.

6.1. Нарисовать оси координат в виде двух перпендикулярных линий, которые пересекаются в центре компонента Image.
6.2. Количество точек, которые образуют график функции, должно быть не менее 10000(n = 10000), чтобы получить видимость сплошной линии.
6.3. Шаг изменения значения x определяется как  .
6.4. При построении нужно учитывать масштаб: ширина компонента Image должна соответствовать длине заданного промежутка. Тогда масштабный коэффициент можно рассчитать по формуле .
6.5. Поскольку расположение осей координат на экране не совпадает с расположением осей, принятым в математике, то нужно преобразовать координаты: точке (0; 0) должна соответствовать точка в центре компонента Image. Для этого полученное значение x нужно увеличить на значение , а значение у на  . Так как ось Y направлена вниз, а не вверх, то значение  нужно изменить, поменяв знак на противоположный. На канве будет закрашиваться точка с координатами ().
6.6. Необходимо учитывать, что при вычислении значения x и y будут вещественными, а значения координат на канве могут быть только целыми. Поэтому перед прорисовкой точки следует преобразовать вещественные числа в целые.

Если в работающем приложении изменить концы промежутка, то график будет порисован поверх уже имеющегося (пример 15.2). 

Пример 15.1. Форма на этапе конструирования:

Обработчик события OnClick для компонента Button1.

void __fastcall TForm1::Button1Click(TObject *Sender)

{

  double x0 = StrToFloat(LabeledEdit1 -> Text);

  double xn = StrToFloat(LabeledEdit2 -> Text);

  //шаг

  double h = (xn - x0) / 10000;

  //центр области построения

  int c_X = Image1 -> Width / 2;

  int c_Y = Image1 -> Height / 2;

  //оси

  Image1 -> Canvas -> MoveTo(0, c_Y);

  Image1 -> Canvas -> LineTo(2 * c_X, c_Y);

  Image1 -> Canvas -> MoveTo(c_X, 0);

  Image1 -> Canvas -> LineTo(c_X, 2*c_Y);

  //коэффициент масштабирования

  double k = 2.*c_/(xn - x0);

  for (double x = x0; x <= xn; x += h){

    double y = x * sin(x);

    //преобразование координат

    int x_ekr = int(* k) + c_X;

    int y_ekr = c_Y - int(y * k);

    Image1 -> Canvas -> Pixels[x_ekr][y_ekr] = clBlue;

  }

  Image1 -> Canvas -> Font -> Color = clBlue;

  Image1 -> Canvas -> TextOut(305"y=x*sin(x)");

}

Работающее приложение:

Пример 15.2. Изменение начальных значений концов промежутка:

Чтобы избежать такой ситуации, перед построением графика нужно очистить компонент. Для этого можно использовать команду:

Image1 -> Picture = NULL;

15.2. Построение диаграмм

Рассмотрим основные принципы построения гистограмм на примерах построения гистограммы и круговой диаграммы. Интерактивность в данном случае обеспечивается данными в файле.

Пример 15.3. Создать проект, в котором необходимо построить гистограмму по данным из массива из n элементов. Значения элементов массива считать из текстового файла. Текстовый файл поместить в папку Win32\Debug. В этом случае для доступа к файлу достаточно прописать имя файла. Если файл хранится в другом месте, то для доступа к файлу необходимо прописать полный путь.

Этапы выполнения задания

  1. Поместить на форму компоненты: изображение (Image) и кнопка (Button).
  2. Изменить свойства Caption у компонента Button1 на «Построить».
  3. Установить размеры Image — 600 × 400.
  4. Написать обработчик события OnClick для компонента Button1, в котором диаграмма строится с помощью прямоугольников.

4.1. Считать данные из файла в массивы: массив d — хранит числа, по которым строится диаграмма; массив s — подписи элементов. Для работы с файлами подключить библиотеку <fstream>. Для чтения строк из файла подключить библиотеку <string>, для работы с. массивами — библиотеку <vector>. Прописать директиву Using NameSpace std для обращения к командам стандартных библиотек.
4.2. Найти максимальный элемент в массиве — элемент, стоящий на месте n_max.
4.3. Рассчитать масштабный коэффициент: . Для того чтобы оставить место для вывода надписей, от высоты формы отнимаем 40.
4.4. В цикле строить n прямоугольников одинаковой ширины. Ширина прямоугольника —   Высота прямоугольника определяется значением , преобразованным к целому типу. Цвет прямоугольников задавать случайно — каждая составляющая цвета изменяется в диапазоне от 1 до 245 (исключаем черный цвет и цвета близкие к белому).
4.5. Вывести надписи над прямоугольниками. Для вывода строк, считанных из файла, их нужно преобразовать так, чтобы можно было вывести на канву. Для этого можно воспользоваться функцией c_str().

Пример 15.4. Создать проект, в котором нужно построить круговую диаграмму по данным из массива. Значения элементов массива считать из текстового файла. Текстовый файл поместить в папку Win32\Debug.

  1. Поместить на форму компоненты: изображение (Image) и кнопка (Button).
  2. Изменить свойства Caption у компонента Button1 на «Построить».
  3. Установить размеры Image — 500 × 500.
  4. Для работы с файлами подключить библиотеку <fstream>. Для чтения строк из файла подключить библиотеку <string>, для работы с массивами — библиотеку <vector>. Для вычислений понадобятся тригонометрические функции, поэтому необходимо подключить библиотеку <cmath>.  Прописать директиву using namespace std для обращения к командам стандартных библиотек.
  5. Написать обработчик события OnClick для компонента Button1, в котором диаграмма строится с помощью секторов.

5.1. Считать данные из файла в массив.
5.2. Найти сумму элементов массива — sum.
5.3. Рассчитать масштабный коэффициент: .
5.4. В цикле строить n  секторов. Цвет сектора задавать случайно — каждая составляющая цвета изменяется в диапазоне от 1 до 245 (исключаем черный цвет и цвета близкие к белому).
5.5. Секторы определяются кругом радиуса R, вписанным в квадрат с координатами диагонали (x1; y1) — (x2; y2). Значения x1 = 50, y1 = 50, x2 = x1 + 2R, y2 = y1 + 2R, R = 200.
5.6. Расчет ключевых точек для построения сектора (см. рисунок).
5.7. Для построения сектора координаты точек (x3; y3) и (x4; y4) нужно преобразовать в экранные: увеличить горизонтальные на , а у вертикальных поменять знак и увеличить на 
5.8. Вывести надписи вверху компонента Image. Для вывода строк, считанных из файла, их нужно преобразовать так, чтобы можно было вывести на канву. Для этого можно воспользоваться функцией c_str(). Местоположение надписи рассчитывается так же и как для гистограммы.

Пример 15.3. Форма на этапе конструирования:

Текстовый файл с данными:

Подключение библиотек:

Обработчик события OnClick для компонента Button1.

void __fastcall TForm1::Button1Click(TObject *Sender)

{

  //чтение данных из файла

  ifstream fin("date.txt");

  int n;

  fin >> n;

  vector <int> d(n);

  vector <string> s(n);

  for(int i = 0; i < n; i++)

    fin >> s[i] >> d[i];

  //поииск максимального

  int n_max = 0;

  for (int i = 0; i < n; i++)

    if (d[i] > d[n_max])

      n_max = i;

  //коэффициент масштабирования

  int  h = Image1 -> Height - 40;

  double k = 1. * h / d[n_max];

  //ширина столбца

  int w = Image1 -> Width/(2 * n + 1);

  int x = w;

  for (int i = 0; i < n; i++) {

    //цвет

    int cr = rand()245 + 1;

    int cg = rand()245 + 1;

    int cb = rand()245 + 1;

    TColor c = TColor (RGB(cr, cg, cb));

    Image1 -> Canvas -> Brush -> Color = c;

    Image1 -> Canvas -> Rectangle

    (x, h + 40, x + w, h - (int)(k * d[i]) + 30);

    //надпись

    Image1 -> Canvas -> Brush -> Color = clWhite;

    Image1 -> Canvas -> Font -> Color = c;

    Image1 -> Canvas -> TextOut

      (x + 33, s[i].c_str());

    //переход к следующему столбцу

    x += 2 * w;

  }

}

Работающее приложение:

Пример 15.4. Форма на этапе конструирования:

Расчет ключевых точек для построения сектора:

Величина угла u2 соответствует текущему значению данных из массива и равна . Величина угла u1 — суммарное значение углов для уже построенных секторов. Вначале u1 = 0.

Значения x3 и y3 — катеты прямоугольного треугольника с углом u1 и гипотенузой равной радиусу круга, поэтому x3 = cos u1, y3 = sin u1.

Аналогично определяем x4 и y4:  y4 = cos (u1 + u2), y4 = sin (u1 + u2).

Обработчик события OnClick для компонента Button1.

void __fastcall TForm1::Button1Click
               (TObject *Sender)

{

  //чтение данных из файла

  ifstream fin("date.txt");

  int n;

  fin >> n;

  vector <int> d(n);

  vector <string> s(n);

  for(int i = 0; i < n; i++)

    fin >> s[i] >> d[i];

  //поииск суммы

  int sum = 0;

  for (int i = 0; i < n; i++)

    sum += d[i];

  //коэффициент масштабирования

  double pi = acos(-1.);

  double k = 2 * pi / sum;

  //определение круга

  double u1 = 0;

  int w = Image1 -> Width/(2 * n + 1);

  int x = w ;

  int R = 200;

  int x1 = 50, y1 = 50;

  int x2 = x1 + 2 * R, y2 = y1 + 2 * R;

  //центр области построения

  int c_X = Image1 -> Width / 2;

  int c_Y = Image1 -> Height / 2;

  for (int i = 0; i < n - 1; i++){

    double u2 = k * d[i];

    int x3 = int (R * cos(u1)) + c_X;

    int y3 = c_Y - int (R * sin(u1));

    int x4 = int (R * cos(u1 + u2)) + c_X;

    int y4 = c_Y - int (R * sin(u1 + u2));

    //цвет

    int cr = rand()255 + 1;

    int cg = rand()255 + 1;

    int cb = rand()255 + 1;

    TColor c = TColor (RGB(cr, cg, cb));

    Image1 -> Canvas -> Brush -> Color = c;

    //сектор

    Image1 -> Canvas -> Pie

    (x1, y1, x2, y2, x3, y3, x4, y4);

    //переход к следующему сектору

    u1 += u2;

    //надпись

    Image1 -> Canvas -> Brush -> Color = clWhite;

    Image1 -> Canvas -> Font -> Color = c;

    Image1 -> Canvas -> 

    TextOut(x + 33, s[i].c_str());

    //переход к следующей надписи

    x += 2 * w;

 Работающее приложение:

15.3. Использование компонента Chart (Диаграмма) для построения графиков функций и диаграмм

С помощью компонента Chart (Диаграмма) можно строить красивые двух- и трехмерные диаграммы на основе различных данных. Компонент Chart находится на палитре TeeChart STD и изображен в виде . Компонент Chart, помещенный на форму, получает имя  ChartN, где N — номер 1, 2, 3… (пример 15.5)

Настройка диаграммы выполняется с помощью редактора, который вызывается двойным щелчком по компоненту (пример 15.6). Параметры отображения диаграммы в окне определяются в разделе Chart, состоящей в свою очередь из набора дополнительных подразделов (General, Axis, Title, Legend, Panal, Walls, 3D). Подробнее о настройке подразделов можно почитать в приложении.

Компонент Chart является контейнером объектов Series — серий данных, которые могут быть визуализированы с помощью различных графических представлений. Свойства серий устанавливаются с помощью редактора диаграмм или непосредственно в программном коде. Для добавления серии используется кнопка Add. Затем происходит выбор внешнего вида диаграммы (пример 15.7) и настройка параметров ее отображения. При добавлении серия получает имя SeriesN, где N — номер 1, 2, 3…

Все серии добавляются на диаграмму со случайными данными, поэтому при программной обработке серию необходимо очистить командой: Series1 -> Clear();

Для добавления данных в серию используется метод Add. Если данные должны отображаться в декартовой системе координат, то используют метод AddXY (пример 15.8).

При использовании компонента Chart масштабирование выполняется автоматически.

Пример 15.9. Создать проект, в котором необходимо построить гистограмму по данным из файла. Для построения диаграммы следует использовать компонент Chart.

Этапы выполнения задания

  1. Поместить на форму компоненты: диаграмма (Chart) и кнопка (Button).
  2. Изменить свойства Caption у компонента Button1 на «Построить».
  3. Выбрать тип диаграммы — гистограмма (Bar).
  4. Настроить следующие свойства:
    4.1. Изменить подпись: Title — заменить текст TChart на Гистограмма.
    4.2. Изменить положение легенды: Legend → Position — заменить Right на Bottom.
  5. Подключить библиотеки для работы с файлами и строками.
  6. Использовать тот же файл, который был создан для примера 15.3.
  7. Написать обработчик события OnClick для компонента Button1.
    7.1. Очистить серию от случайных данных.
    7.2. В цикле считывать данные из файла и добавлять их к данным серии.

Пример 15.10. Создать проект, в котором необходимо построить графики функций y = x cosx  и   в одной системе координат. Для построения диаграммы следует использовать компонент Chart.

Этапы выполнения задания

  1. Поместить на форму компоненты: диаграмма (Chart), два компонента LabeledEdit и компонент Button.
  2. Изменить свойства Caption у компонентов LabeledEdit1, LabeledEdit2 на x0 и xn соответственно.
  3. Изменить свойства Text у компонентов LabeledEdit1 и LabeledEdit2 на -30 и 30 соответственно.
  4. Изменить свойства Caption у компонента Button1 на «Построить».
  5. Добавить две серии, для которых выбрать тип диаграммы — точечная (Point), убрать галочку 3D.
  6. Изменить название серий: кнопка Title — заменить Series1 на y=x*x+xcosx и Series2 на y=(x(x^2+5)^(1/2) / (x-3)
  7. Настроить следующие свойства:
    7.1. Свойсво Title — удалить текст TChart.
    7.2. Изменить положение легенды: Legend → Position — заменить Right на Bottom.
    7.3. Изменить положение осей: Axis → Left значение Axis → Position — установить 50%; аналогично для Axis → Bottom изменить значение Axis → Position на 50%.
    7.4. Для каждой серии:
       7.4.1. изменить размер точки: Size — 1;
       7.4.2. удалить границу вокруг точки: Border — убрать галочку Visible.
  8. Написать обработчик события OnClick для компонента Button1.
    8.1. Очистить серии от случайных данных.
    8.2. В цикле с шагом 0.001вычислять значения функций и добавлять данные к соответствующей серии.
    8.3. Для второй серии добавить проверку на равенство знаменателя нулю. Если знаменатель по модулю меньше 0.01, то следует пропускать итерацию цикла.

*Пример 15.11. Создать проект, в котором необходимо построить астроиду, заданную параметрическими уравнениями:

 .

Для построения диаграммы использовать компонент Chart.

Этапы выполнения задания

  1. Поместить на форму компоненты: диаграмма (Chart), компонент LabeledEdit и компонент Button.
  2. Изменить свойства Caption у компонента LabeledEdit1 на а.
  3. Изменить свойства Text у компонента LabeledEdit1 на 5.
  4. Изменить свойства Caption у компонента Button1 на «Построить».
  5. Добавить серию, для которой выбрать тип диаграммы — точечная (Point).
  6. Настроить следующие свойства:
    6.1. Изменить подпись: Title — заменить текст TChart на Астроида.
    6.2. Удалить легенду: Legend → Style — убрать галочку Visible.
    6.3. Положение осей и размер точки установить так же, как и в примере 15.10.
  7. Написать обработчик события OnClick для компонента Button1.
    7.1. Очистить серии от случайных данных.
    7.2. В цикле изменять параметр t от 0 до 2p[1] с шагом 0.001.
    7.3. Вычислять значения x и y и добавлять данные к серии.

Пример 15.5. Компонент Chart на форме:

Пример 15.6. Редактор диаграммы:

Пример 15.7. Выбор типа диаграммы:

Пример 15.8. Методы добавления данных в серию:

  Series1->Add(z, s, color);  

Параметры:

z — число, соответствующее значению данных;

s — подпись данных;

color — цвет.

   Series1-> AddXY(x,y,"",color);  

Параметры:

x, y — координаты отображаемой точки в декартовой системе координат;

"" — здесь может быть текст подписи к точке;

color — цвет.

Параметр color может быть опущен. В этом случае цвет элемента диаграммы определяется настройками редактора.

Пример 15.9. Форма на этапе конструирования:

Обработчик события OnClick для кнопки.

void __fastcall TForm1::Button1Click
                (TObject *Sender)

{

  ifstream fin("date.txt");

  int n;

  fin >> n;

  Series1 -> Clear();

  for(int i = 0; i < n; i++) {

    string s;

    int d;

    fin >> s >> d;

    Series1 -> Add(d, s.c_str());

  }

}

 Работающее приложение:

Пример 15.10. Форма на этапе конструирования:

Изменение названия серии:

Обработчик события OnClick для кнопки

void __fastcall TForm1::Button1Click
                TObject *Sender)

{

  double x0 = StrToFloat

  (LabeledEdit1 -> Text);

  double xn = StrToFloat

  (LabeledEdit2 -> Text);

  Series1 -> Clear();

  Series2 -> Clear();

  for (double x = x0; x <= xn; x += 0.001) {

    double y = x * x  + x * cos(x);

    Series1 -> AddXY(x, y, "", clBlue);

    if ( abs(x - 3) < 0.01 ) continue;

    double y1 = x * sqrt(x * x + 5) / (x - 3);

    Series2 -> AddXY(x, y1, "", clRed);

  }

}

Работающее приложение:

Пример 15.11. Форма на этапе конструирования:

Обработчик события OnClick для кнопки.

void __fastcall TForm1::Button1Click
                (TObject *Sender)

{

  double a = StrToFloat

   (LabeledEdit1 -> Text);

  Series1 -> Clear();

  for (double t = 0

       t <= 2 * acos(-1.);

        t += 0.001) {

    double x = a * cos(t) * cos(t) * cos(t);

    double y = a * sin(t) * sin(t) * sin(t);

    Series1 -> AddXY(x, y, "", clRed);

  }

} 

Работающее приложение:

пример

Вопросы к параграфу

1. Какие расчеты используют для преобразования координат при построении графиков функции на экране компьютера?

2. Как вычислить коэффициент масштабирования при построении гистограммы?

3. Как вычислить коэффициент масштабирования при построении круговой диаграммы?

4. Для чего предназначен компонент Chart?

5. Какие методы Series позволяют добавлять данные на диаграммы?

Упражнения

  

1. Добавьте в проект 15.1 следующие возможности:

  1. Оси координат со стрелками и подписями.
  2. Единичный отрезок на оси X.
  3. График функции y = 0.3x2 – 4x + 2, в той же системе координат, красным цветом.

2. Измените проект из примера 15.3 так, чтобы строилась линейчатая диаграмма (столбики расположены горизонтально).

3. Используя расчеты из примера 15.3, постройте следующие диаграммы:

1. в виде ломаной линии;

2. точечная (в качестве «точки» можно использовать круг диаметра 10 пикселей или символ «*», для которого установлен размер шрифта 20).

4. Используя расчеты из примера 15.4, постройте следующие диаграммы:

1. полукруг;

*2. роза ветров.

5. Постройте диаграммы используя компонент Chart:

1.

2.

3.

6. Постройте в одной системе координат графики функций, используя компонент Chart. Предусмотрите поля для ввода значений параметров.

a) 
b) .

7 *. Постройте графики кривых, заданных параметрическими уравнениями, используя компонент Chart:

1. Архимедова спираль:

2. Роза:

 

3. Улитка Паскаля: