Опубликован: 10.03.2009 | Доступ: свободный | Студентов: 2295 / 280 | Оценка: 4.31 / 4.07 | Длительность: 09:23:00
Лекция 1:

Программирование под Windows с использованием Win API

Лекция 1: 123 || Лекция 2 >

Пример разложения в ряд функции. Графический вывод

Проиллюстируем рассмотренный в предыдущем параграфе теоретичекий материал на примере написания Windows-приложения решения задачи о разложении в ряд некоторой функции.

Задача: Разложить в ряд Тейлора в окрестности точки 0 функции sin(x), cos(x) и вывести в окне график функции .

Напишем функции вычисления синуса и косинуса – разложения в ряд Тейлора в окрестности точки 0. Разложения в ряд имеют вид:

sin(x)=x-\frac{x^3}{3!}+...+(-1)^{n-1}\cdot\frac{x^{2n-1}}{(2n-1)!}}cos(x)=1-\frac{x^2}{2}+...+(-1)^{n}\cdot\frac{x^{2n}}{(2n)!}}

Радиус сходимости для этих рядов – \infty.

const double epsilon = 0.0000001;
const double pi = 3.14159265;
const double x_start = -2*pi;
const double x_end = 2*pi;

double sin_e(double arg, double eps)
{
  double result = 0, rn = arg;
  for(int i = 1; ;i++)
  {
    if(rn < eps && rn > -eps) return result;  
    result += rn;
    rn = -rn*arg*arg/(i+1)/(i+2);  
    i++;  
  }
}

double cos_e(double arg, double eps)
{
  double result = 0, rn = 1;
  for(int i = 0; ;i++)
  {
    if(rn < eps && rn > -eps) return result;  
    result += rn;
    rn = -rn*arg*arg/(i+1)/(i+2);  
    i++;  
  }
}

Для дальнейшего решения задачи – вывода графика функции в клиентском окне, будем обрабатывать сообщения, которые будут посылаться окну. Когда необходима перерисовка окна (изменились размеры окна, часть окна перекрылась другим окном и т.п.), система посылает окну сообщение WM_PAINT.

Добавим функции, которые будут выводить в клиентскую часть окна график и координатные оси, а также, необходимые ветви case в операторе switch.

Для построения изображения используем API функции операционной системы: MoveToEx(...), LineTo(...), GetClientRect(...) и т.д. Информацию об этих функциях можно получить в справочной системе.

void DrawAxis(HDC hdc, RECT rectClient)
{
  HPEN penGraph = CreatePen(PS_SOLID,2,RGB(0,0,255));
  HGDIOBJ gdiOld = SelectObject(hdc, penGraph);
  MoveToEx(hdc, 0, rectClient.bottom/2, NULL);
  LineTo(hdc, rectClient.right, rectClient.bottom/2);
  LineTo(hdc, rectClient.right - 5, rectClient.bottom/2 + 2);
  MoveToEx(hdc, rectClient.right, rectClient.bottom/2, NULL);
  LineTo(hdc, rectClient.right - 5, rectClient.bottom/2 - 2);
  MoveToEx(hdc, rectClient.right/2, rectClient.bottom, NULL);
  LineTo(hdc, rectClient.right/2, rectClient.top);
  LineTo(hdc, rectClient.right/2 - 2, rectClient.top + 5);
  MoveToEx(hdc, rectClient.right/2, rectClient.top, NULL);
  LineTo(hdc, rectClient.right/2 + 2, rectClient.top + 5);
  SelectObject(hdc, gdiOld);
}

void DrawGraph(HDC hdc, RECT rectClient)
{
  HPEN penGraph = CreatePen(PS_SOLID,2,RGB(255,0,0));
  HGDIOBJ gdiOld = SelectObject(hdc, penGraph);
  double x_current = x_start;
  double step = (x_end - x_start)/rectClient.right;
  double y_start = cos_e(x_start, epsilon) + cos_e(x_start, epsilon);
  MoveToEx(hdc, 0, int(-y_start/step) + rectClient.bottom/2, NULL);
  while(x_current < x_end)
  {  
    x_current += step;
    double y_next = cos_e(x_current, epsilon) + cos_e(x_current, epsilon);
    LineTo(hdc, int(x_current/step) + rectClient.right/2, int(-y_next/step) + rectClient.bottom/2);
  }
  SelectObject(hdc, gdiOld);
}

void OnPaint(HWND hwnd)
{
  PAINTSTRUCT ps;
  RECT rectClient;
  HDC hdc = BeginPaint(hwnd,&ps);
  GetClientRect(hwnd, &rectClient);
  DrawAxis(hdc, rectClient);
  DrawGraph(hdc, rectClient);
  ValidateRect(hwnd,NULL);
  EndPaint(hwnd,&ps);
}

LONG WINAPI WndProc(HWND hwnd, UINT Message, WPARAM wparam, LPARAM lparam)
{
  switch (Message)
  {
    case WM_PAINT:
      OnPaint(hwnd);
    break;
    case WM_MOUSEMOVE:
      SetCapture(hwnd);
      SetCursor(LoadCursor(NULL,IDC_ARROW));
      ReleaseCapture();
    break;
    case WM_WINDOWPOSCHANGED:
      UpdateWindow(hwnd);
    break;
    case WM_DESTROY: PostQuitMessage(0); break;
    default: return DefWindowProc(hwnd, Message, wparam, lparam);
  }
  UpdateWindow(hwnd);
  return 0;
}
Листинг 1.1.

Функция DrawGraph(...) выводит на экран график, функция DrawAxis(...) выводит координатные оси. При выводе графика функции на экран используем преобразование системы координат окна приложения в логическую систему координат и наоборот. Подробно этот вопрос рассмотрен в следующей лекции. В результате в клиентской области окна получим искомый график функции : рис. 1.1

Построение графика функции

Рис. 1.1. Построение графика функции
Лекция 1: 123 || Лекция 2 >