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

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;