Построение графиков в Delphi.

Начало

Наверное, все видели программы, которых довольно много, для построения всяческих графиков. Если Вы хотите написать что-то подобное на Delphi, то эта статья для Вас. В самых-самых программах Вам предлагается ввести формулу строкой, а не выбирать функции из списка. Самым сложным (?) элементом таких программ является текстовый анализатор. В данной статье я не собираюсь рассказывать, как пишутся текстовые анализаторы. Я собираюсь рассказать о некоторых основных принципах построения графиков, и работы с графикой в среде Delphi без использования специальных графических платформ, таких как DirectX или OpenGL.

 

Введение

 

В Delphi для прорисовки различных элементов управления используется специальный класс TCanvas. Можно выделить  4 основных направления, в которых используется этот класс:

1. Загрузка и хранение графических изображений.

2. Создание новых и изменение хранимых изображений с помощью пера, кисти, шрифта.

3. Рисование и/или закраска фигур, линий, текстов.

4. Комбинирование изображений.

 

Как Вы уже поняли, мы пойдем по третьему направлению.

Теперь давайте рассмотрим некоторые свойства и методы класса TCanvas. Сразу скажу, что я буду рассматривать далеко не все методы и свойства класса TCanvas, а лишь те, которые мы будем использовать потом.

 

TCanvas

 

Свойства:

 

1. property Brush: TBrush;

Данное свойство позволяет определить цвет (Brush.Color) и стиль (Brush.Style) заполнения замкнутых фигур и фона.

 

2. property ClipRect: TRect; - read-only

Данное свойство позволяет получить доступную область рисования. Вне этой области рисовать невозможно.

Тип TRect, описанный в модуле Windows, имеет следующий синтаксис:

Type

  TRect = record

   Case integer of

     0: (Left, Top, Right, Bottom: Integer);

    1: (TopLeft, BottomRight: TPoint);

 end;

 

3. property Pen: TPen;

Данное свойство позволяет задать цвет пера, рисующего фигуры или линии.

 

 

Методы:

 

1. procedure FillRect (const Rect: TRect);

Метод позволяет заполнить цветом прямоугольную область холста Rect, используя текущее значение кисти Brush.

 

2. procedure MoveTo (x, y: integer);

Метод позволяет переместить перо в точку (X, Y).

 

3. procedure LineTo (x, y: integer);

Метод позволяет нарисовать прямую линию, которая начинается с текущей позиции пера и заканчивается точкой (x, y). При рисовании используются текущие установки пера Pen.

 

Ну вот, пожалуй, и все, что нам будет нужно, для успешного построения графика.

 

Построение графика. Теория.

 

Для начала предлагаю немного теории. Мы собираемся писать процедуру построения графика функции на определенной поверхности, заданной свойством Canvas. Я предлагаю поставить оси координат в середине этой области, а график растянуть так, чтобы он растянулся на всю область. Строить мы будем методом lineto. Поэтому нам нужно определиться с шагом изменения величины аргумента. Я предлагаю взять его обратным к масштабу по оси ординат. Так наш график будет выглядеть плавно при любой функции и любом начальном и конечном значении абсциссы. Масштаб по оси абсцисс считается, отношение ширины поверхности к разнице максимального и минимального значения абсциссы. Масштаб по оси ординат считается аналогично: отношение высоты поверхности к разнице между максимальным и минимальным значениями данной функции на данном интервале.

 

Процедура DrawGraph

 

Ну вот и все с теорией и я приведу полный код функции, а потом разберем его.

 

Type TFunc = function (x: real): real;

procedure DrawGraph (f: TFunc; a: real; b: real; C: TCanvas);

var x, y, h: real;

    max, min: real;

    sx, sy: real;

    xmid, ymid: integer;

begin

sx := (c.ClipRect.Right)/(b-a);

 h := 1/sx;

 xmid := c.ClipRect.Right div 2;

 ymid := c.ClipRect.Bottom div 2;

 x := a;

 max := f( x);

 min := max;

 while x<=b do

  begin

   y := f( x);

   if y<min then min := y;

   if y>max then max := y;

   x := x + h;

  end;

 sy := c.ClipRect.Bottom/ (max-min);

 c.Brush.Color := clBlack;

 c.FillRect(Rect(0, 0, c.ClipRect.Right, c.ClipRect.Bottom));

 c.Pen.Color := clYellow;

 c.MoveTo(0, ymid);

 c.LineTo(c.ClipRect.Right, ymid);

 c.MoveTo(xmid, 0);

 c.LineTo(xmid, c.ClipRect.Bottom);

 x := a;

 y := f(x);

 c.Pen.Color := clWhite;

 c.MoveTo(xmid+round(sx*x), ymid-round(sy*y));

 while x<=b do

  begin

   y := f(x);

   c.LineTo(xmid+round(sx*x), ymid-round(sy*y));

   x := x + h;

  end;

end;

 

А теперь, если Вы чего-либо не поняли, давайте разберем этот код.

 

Type TFunc = function (x: real): real;

 

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

 

procedure DrawGraph (f: TFunc; a: real; b: real; C: TCanvas);

 

Заголовок функции. Параметры: f – функция, график, которой будем троить. a – начальное значение переменной “x”. b – конечное значение переменной “x”. C – канва, на которой будем рисовать.

 

 sx := (c.ClipRect.Right)/(b-a);

 h := 1/sx;

 xmid := c.ClipRect.Right div 2;

 ymid := c.ClipRect.Bottom div 2;

 x := a;

 max := f( x);

 min := max;

 while x<=b do

  begin

   y := f( x);

   if y<min then min := y;

   if y>max then max := y;

   x := x + h;

  end;

 sy := c.ClipRect.Bottom/ (max-min);

 

В этом куске кода мы считаем масштабы по осям координат, и среднее значения высоты и ширины канвы, чтобы отобразить оси координат.

 

 c.Brush.Color := clBlack;

 c.FillRect(Rect(0, 0, c.ClipRect.Right, c.ClipRect.Bottom));

 c.Pen.Color := clYellow;

 c.MoveTo(0, ymid);

 c.LineTo(c.ClipRect.Right, ymid);

 c.MoveTo(xmid, 0);

 c.LineTo(xmid, c.ClipRect.Bottom);

 

Здесь мы заливаем всю канву черным цветом и рисуем желтым цветом оси координат.

 

 x := a;

 y := f(x);

 c.Pen.Color := clWhite;

 c.MoveTo(xmid+round(sx*x), ymid-round(sy*y));

 while x<=b do

  begin

   y := f(x);

   c.LineTo(xmid+round(sx*x), ymid-round(sy*y));

   x := x + h;

  end;

 

Ну и, наконец, нарисовали график нужной нам функции.

 

Небольшой пример:

 

Положим на форму одну кнопку и один компонент TImage. Создадим обработчик функции OnClick для кнопки примерно следующего характера, и следующую функцию для расчета функции

 

Function f(x: real): real;

Begin

 Result := sin(x)*cos(x);

End;

 

procedure TForm1.Button1Click(Sender: TObject);

begin

 DrawGraph (f, -10, 10, Image1.Canvas);

end;

 

Вот и все. Если у Вас будут вопросы, пишите их на адрес cpas@realcoding.net

© CPAS, 2004г.

 



Опубликовал admin
5 Июн, Суббота 2004г.



Программирование для чайников.