Графика в Delphi и Lazarus



Содержание:
  • Объекты для работы с графикой
  • Создание приложения "Построитель графиков"


  • Объекты для работы с графикой


    Для рисования в Delphi и Lazarus можно воспользоваться следующими компонентами: Рисовать на самой форме - Form; на компоненте Image (закладка Standard); на компоненте PaintBox (закладка System).
    При рисовании на компонентах Form и PaintBox следует учитывать то обстоятельство, что графическое изображение исчезает при изменении положения окна, сворачивании и разворачивании программы, при изменении размеров окна и т.д. Для сохранения изображения на этих компонентах следует создать событие onPaint, в котором должны быть прописаны все команды восстановления изображения. Компонент Image не требует перерисовки, и изображение на нем сохраняется на протяжении всего времени работы с программой. В связи с этим, на уроках, будем пользоваться только этим компонентом. Все три перечисленные компонента имеют объект - наследник Canvas (Canvas - означает холст для рисования), а сам холст имеет определенные свойства, которые будут перечислены ниже. Для того, чтобы не писать такие строки как например: Image1.Canvas.Font.Color:= clBlack, следует воспользоваться оператором объединения Width. Ниже описаны все возможные свойства объектов, которые можно разместить на холсте - объекте Canvas:
    • Настройки шрифта для вывода строк на канву
      with Image1.canvas.font do
      begin
        color:= clNavy; // Цвет символов
        style:= []; //Начертание символов
        name:= 'Arial Cyr'; //Имя шрифта
        size:= 14; //Размер шрифта
      end;
      В приведённом выше фрагменте процедуры настройки шрифта - стиль (Style) это массив стилей, поэтому стили можно складывать. Массив имеет следующие значения:
      [] - пустое значение - нормальный шрифт;
      [fsBold] - жирный шрифт;
      [fsItalic] - шрифт Италик (наклонный);
      [fsStrikeOut] - Перечеркнутый шрифт;
      [fsUnderLine] - Подчеркнутый шрифт;
      Имена шрифтов (name) - все имена, содержащиеся в операционной системе, например Times New Roman, Ms Sans Serif, Courier New, ...
      Размер шрифта (Size) - может принимать значения от 1 до 32768.
      Для вывода строки текста, с настроенным предварительно шрифтом, на канву следует воспользоваться процедурой TextOut(x,y,'Строка текста');. Не следует забывать, что эта процедура должна относиться к определенному холсту (в программе холстов может быть много), поэтому следует четко указывать объект на котором мы хотим разместить надпись, например так: Image25.canvas.textout(10,20,'Строка');. Координаты x и y определяют начало первого символа надписи на холсте (в пикселях).
    • Следующим шагом при рисовании является настройка пера (карандаша) для рисования - свойство Pen:
      with Image1.canvas.pen do
      begin
      width:= 2; // Толщина карандаша в пикселях
      color:= clBlack; // Цвет карандаша
      end;
      Сам холст тоже может иметь цвет, который задается свойством canvas.brush.color:= clWhite;
      Произведя все настройки, можно начинать рисование.
      Для рисования на холсте имеются следующие процедуры:
      with image1.canvas do
      begin
      MoveTo(10,10); // Перемещает перо в точку с координатами 10,10
      LineTo(100,100); //Рисуем линию из точки 10,10 к точке 100,100
      Rectangle(10,10,100,100); // Рисуем прямоугольник с координатами верхнего левого угла 10,10 и координатами нижнего правого угла 100, 100
      Ellipse(10,10,100,100); // Рисуем эллипс вписанный в виртуальный прямоугольник с начальной координатой 10,10 и конечной координатой 100,100
      end; {width}
      На самом деле процедур для рисования намного больше, нежели чем перечислено выше, причем с каждой новой версией Delphi их количество увеличивается, поэтому для рисования следует воспользоваться справочником графических процедур и функций для конкретной версии Delphi или Lazarus.
      Еще одно свойство, которое часто используется для рисования, это свойство Pixels. Pixels - это массив всех точек в области холста. Пиксели можно как записывать на холст с определенным цветом: Image1.Canvas.Pixels[x,y]:= clRed;, так и считывать с холста цвет пикселя: variable:= Image1.canvas.pixels[x,y];. В приведенном выше свойстве Pixels - координатами пикселя являются X и Y, variable - переменная, которая должна иметь тип LongInt.


    • Создание приложения "Построитель графиков"
      Создайте новый проект. Разместите на окне компонент панель и присвойте панели свойство Align = alBottom. Панель будет расположена внизу окна. Установите в окне компонент Image и присвойте свойству Align значение alClient. Форме присвойте свойству BorderStyle значение bsSingle, а свойству caption значение "Построитель графиков функций".
      Установите на панель строчный редактор Edit1 - в него мы будем вводить имя функции. Затем установите на панель редакторы Edit2 и Edit3 в которые мы будем вводить начальное и конечное значение угла функции соответственно.
      Еще нам понадобятся 2-е кнопки (Button1, Button2). Первая будет очищать лист, подготавливая его для вывода графика, а вторая будет выводить на лист непосредственно график по заданным параметрам введенным в редакторы. Кнопке Button1 присвойте заголовок "Строить", а кнопке Button2 - заголовок "Очистить". У вас должно получиться приложение показанное на рисунке:



      Сначала следует создать событие onCreate для формы:
      procedure TForm1.FormCreate(Sender: TObject);
      begin
      // Очищаем редакторы и присваиваем значения по умолчанию
        edit1.text:= 'SIN';
        edit2.text:= '1';
        edit3.text:= '600';
      end;
      Затем, нам следует создать событие onClick на нажатие кнопки "Очистить":
      procedure TForm1.Button2Click(Sender: TObject);
      var r: TRect; // обьявляем переменную типа прямоугольник
      begin
      // Присваиваем переменной r размер нашего листа Image1
        r:= rect(0, 0, image1.width, image1.height);
        with Image1.canvas do
        begin
        brush.style:= bsSolid; // Присваиваем кисти тип заливки - "полная"
        brush.color:= clWhite; //делаем цвет холста белым
        fillrect(r); //заливаем холст заказанным цветом
        pen.color:= clRed; //задаем цвет карандаша: красный
        // Рисуем рамку по периметру листа
        rectangle(2, 2, image1.width-2, image1.height-2);
      // Рисуем ось Х для будущего графика посредине листа
        moveto(2,image1.Height div 2);
        lineto(image1.width-2, Image1.Height div 2);
        end; end;

      И наконец, нам осталось создать событие на построение графика вычисления синуса или косинуса - нажатие кнопки Button1- "Строить":
      procedure TForm1.Button1Click(Sender: TObject);
      var
      alpha1, alpha2: Integer; // переменные для начального и конечного значения угла
        z: integer; // переменная для организации цикла
        q: integer; // внутренний счетчик
        fun: integer; // Значение функции в цикле
      begin
        alpha1:= StrToInt(edit2.text); //Считываем начальное значение угла
        alpha2:= StrToInt(Edit3.Text); // Конечное значение угла
        q:= 2;
      for z:= alpha1 to alpha2 do // Создаем цикл от начального до конечного значения угла
      begin
        if UpperCase(Edit1.text) = 'SIN' then
        fun:= round(sin(z*3.14/180)*60);
        if UpperCase(Edit1.text) = 'COS' then
        fun:= round(cos(z*3.14/180)*80);
        image1.canvas.pixels[q,fun+ image1.Height div 2]:= clBlack;
        inc(q);
      end;
      end;
      Рассмотрим подробнее действия происходящие в цикле:
      Строка: if UpperCase(Edit1.text) = 'SIN' then fun := round(sin(z*3.14/180)*60);
      означает, что если строка преобразованная к символам верхнего регистра из редактора ввода функции (Edit1) равна значению 'SIN', то следует вычислять синус для всех значений z и присваивать переменной fun. Так как эта переменная целого типа, то значение функции следует округлять до целого значения функцией round. Так как аргумент функции должен быть в радианах, а мы вводим угол в градусах, то следует преобразовать градусы в радианы - (z*3.14/180). Далее мы помножаем значение синуса на 60. 60 это масштабный коэффициент амплитуды функции, чем он больше, тем больше амплитуда кривой по оси Y.
      Аналогичным образом устроена строка:
      if UpperCase(Edit1.text) = 'COS' then fun:= round(cos(z*3.14/180)*80); только здесь производится вычисление косинуса и масштабный коэффициент равен 80.
      Строка - image1.canvas.pixels[q, fun+ image1.Height div 2]:= clBlack; означает следующее: последовательно, точка за точкой выводим на экран график выбранной функции. С каждым тактом цикла смещаем точку по оси Х на расстояние q, а по оси Y смещаем на значение функции (fun) и плюс ? высоты листа, для того чтобы график проходил положительными значениями над осью Х, а отрицательными значениями под осью Х. Последняя строка цикла inc(q) - увеличение значения q на 1 с каждым тактом цикла. Запустите полученную программу на исполнение, нажмите кнопку "Очистить", а затем кнопку "Строить" - вы получите график синуса со значениями по умолчанию. Затем введите другое значение например COS и нажмите кнопку "Строить", у вас должно получиться примерно то, что изображено на рисунке.






       ©Гуков Константин Михайлович 2006 - 2011     Почта: [email protected]