Графические возможности Delphi


Delphi позволяет программисту разрабатывать программы, которые могут выводить графику: схемы, чертежи, иллюстрации.
Программа выводит графику на поверхность объекта (формы или компонента Image). Поверхности объекта соответствует свойство canvas. Для того чтобы вывести на поверхность объекта графический элемент (прямую линию, окружность, прямоугольник и т. д.), необходимо применить к свойству canvas этого объекта соответствующий метод. Например, инструкция Form1.Canvas.Rectangle (10,10,100,100) вычерчивает в окне программы прямоугольник.
Холст
Как было сказано ранее, поверхности, на которую программа может выводить графику, соответствует свойство Canvas. В свою очередь, свойство canvas — это объект типа TCanvas. Методы этого типа обеспечивают вывод графических примитивов (точек, линий, окружностей, прямоугольников и т. д.), а свойства позволяют задать характеристики выводимых графических примитивов: цвет, толщину и стиль линий; цвет и вид заполнения областей; характеристики шрифта при выводе текстовой информации.
Методы вывода графических примитивов рассматривают свойство Canvas как некоторый абстрактный холст, на котором они могут рисовать (canvas переводится как "поверхность", "холст для рисования"). Холст состоит из отдельных точек — пикселов. Положение пиксела характеризуется его горизонтальной (X) и вертикальной (Y) координатами. Левый верхний пиксел имеет координаты (0, 0). Координаты возрастают сверху вниз и слева направо (Значения координат правой нижней точки холста зависят от размера холста.
Размер холста можно получить, обратившись к свойствам Height и width области иллюстрации (image) или к свойствам формы: ClientHeight и Clientwidth.

Карандаш и кисть


Художник в своей работе использует карандаши и кисти. Методы, обеспечивающие вычерчивание на поверхности холста графических примитивов, тоже используют карандаш и кисть. Карандаш применяется для вычерчивания линий и контуров, а кисть — для закрашивания областей, ограниченных контурами.
Карандашу и кисти, используемым для вывода графики на холсте, соответствуют свойства Реn (карандаш) и Brush (кисть), которые представляют собой объекты типа треп и TBrush, соответственно. Значения свойств этих объектов определяют вид выводимых графических элементов.
Карандаш
Карандаш используется для вычерчивания точек, линий, контуров геометрических фигур: прямоугольников, окружностей, эллипсов, дуг и др. Вид линии, которую оставляет карандаш на поверхности холста, определяют свойства объекта треп, которые перечислены в табл. 10.1.
Таблица 10.1. Свойства объекта треп (карандаш)

Свойство Color задает цвет линии, вычерчиваемой карандашом. В табл. 10.2 перечислены именованные константы (тип TCoior), которые можно использовать в качестве значения свойства color.
Таблица 10.2. Значение свойства Color определяет цвет линии

Свойство width задает толщину линии (в пикселах). Например, инструкция Canvas. Pen. width: =2 устанавливает толщину линии в 2 пиксела.
Свойство style определяет вид (стиль) линии, которая может быть непрерывной или прерывистой, состоящей из штрихов различной длины. В табл. 10.3 перечислены именованные константы, позволяющие задать стиль линии. Толщина пунктирной линии не может быть больше 1. Если значение свойства Pen.width больше единицы, то пунктирная линия будет выведена как сплошная.
Таблица 10.3. Значение свойства Реn. туре определяет вид линии

Свойство Mode определяет, как будет формироваться цвет точек линии в зависимости от цвета точек холста, через которые эта линия прочерчивается. По умолчанию вся линия вычерчивается цветом, определяемым значением свойства Pen.Color.
Однако программист может задать инверсный цвет линии по отношению к цвету фона. Это гарантирует, что независимо от цвета фона все участки линии будут видны, даже в том случае, если цвет линии и цвет фона совпадают.
В табл. 10.4 перечислены некоторые константы, которые можно использовать в качестве значения свойства Pen.Mode.
Таблица 10.4. Значение свойства Реп. Mode влияет на цвет линии

Кисть


Кисть (canvas.Brush) используется методами, обеспечивающими вычерчивание замкнутых областей, например геометрических фигур, для заливки (закрашивания) этих областей. Кисть, как объект, обладает двумя свойствами, перечисленными в табл. 10.5.
Таблица 10.5. Свойства объекта TBrush (кисть)

Область внутри контура может быть закрашена или заштрихована. В первом случае область полностью перекрывает фон, а во втором — сквозь незаштрихованные участки области будет виден фон.
В качестве значения свойства Color можно использовать любую из констант типа TColor (см. список констант для свойства Pen.color в табл. 10.2).
Константы, позволяющие задать стиль заполнения области, приведены в табл. 10.6.
Таблица 10.6. Значения свойства Brush, style определяют тип закрашивания

В качестве примера в листинге 10.1 приведена программа Стили заполнения областей, которая в окно (выводит восемь прямоугольников, закрашенных черным цветом с использованием разных стилей.
Листинг 10.1. Стили заполнения областей
unit brustyle_; interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs, ExtCtrls;
type
TForm1 = class(TForm)
procedure FormPaint(Sender: TObject);
private
{ Private declarations}
public
{ Public declarations )
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
// перерисовка формы
procedure TForm1.FormPaint(Sender: TObject);
const
bsName: array[1..8] of string =
('bsSolid','bsClear','bsHorizontal',
'bsVertical','bsFDiagonal','bsBDiagonal',
'bsCross','bsDiagCross');
var
x,y: integer; // координаты левого верхнего угла прямоугольника
w,h: integer; // ширина и высота прямоугольника
bs: TBrushStyle;// стиль заполнения области
k: integer; // номер стиля заполнения
i,j: integer;
begin
w:=40; h:=40; // размер области(прямоугольника)
у:=20;
for i:=l to 2 do
begin
х:=10;
for j:=1 to 4 do
begin
k:=j+(i-1)*4; // номер стиля заполнения
case k of
1: bs = bsSolid;
2: bs = bsClear;
3: bs = bsHorizontal;
4: bs = bsVertical;
5: bs = bsFDiagonal;
6: bs = bsBDiagonal;
7: bs = bsCross;
8: bs = bsDiagCross; end;
// вывод прямоугольника
Canvas.Brush.Color := clGreen;
// цвет закрашивания — зеленый
Canvas.Brush.Style := bs;
// стиль закрашивания
Canvas . Rectangle (x, y, x+w, y-t-h) ;
// вывод названия стиля
Canvas.Brush.Style := bsClear;
Canvas.TextOut(x, y-15, bsName[k]);
// вывод названия стиля
x := x+w+30;
end;
у := y+h+30;
end;
end;
end.
Вывод текста
Для вывода текста на поверхность графического объекта используется метод TextOut. Инструкция вызова метода TextOut в общем виде выглядит следующим образом:
Объект.Canvas.TextOut(x, у, Текст)
где:

  • объект — имя объекта, на поверхность которого выводится текст;
  • х, у — координаты точки графической поверхности, от которой выполняется вывод текста (— переменная или константа символьного типа, значение которой определяет выводимый методом текст.
    Шрифт, который используется для вывода текста, определяется значением свойства Font соответствующего объекта canvas. Свойство Font представляет собой объект типа TFont. В табл. 10.7 перечислены свойства объекта TFont, позволяющие задать характеристики шрифта, используемого методами TextOut и TextRect для вывода текста.
    Таблица 10.7. Свойства объекта TFont

Внимание!
Область вывода текста закрашивается текущим цветом кисти. Поэтому перед выводом текста свойству Brush.Color нужно присвоить значение bsClear или задать цвет кисти, совпадающий с цветом поверхности, на которую выводится текст.
Следующий фрагмент программы демонстрирует использование функции Textout для вывода текста на поверхность формы:
with Form1.Canvas do begin
// установить характеристики шрифта
Font.Name := 'Tahoma';
Font.Size := 20;
Font.Style := [fsltalic, fsBold] ;
Brush.Style := bsClear; // область вывода текста не закраши-
TextOut(0, 10, 'Borland Delphi 7');
end;
После вывода текста методом Textout указатель вывода (карандаш) перемещается в правый верхний угол области вывода текста.
Иногда требуется вывести какой-либо текст после сообщения, длина которого во время разработки программы неизвестна. Например, это может быть слово "руб." после значения числа, записанного прописью. В этом случае необходимо знать координаты правой границы уже выведенного текста. Координаты правой границы текста, выведенного методом Textout, можно получить, обратившись к свойству PenPos.
Следующий фрагмент программы демонстрирует возможность вывода строки текста при помощи двух инструкций Textout.
with Form1.Canvas do begin
TextOut(0, 10, 'Borland ') ;
TextOut(PenPos.X, PenPos.Y, 'Delphi 7');
end;
Методы вычерчивания графических примитивов
Любая картинка, чертеж, схема могут рассматриваться как совокупность графических примитивов: точек, линий, окружностей, дуг и др. Таким образом, для того чтобы на экране появилась нужная картинка, программа должна обеспечить вычерчивание (вывод) графических примитивов, составляющих эту картинку.
Вычерчивание графических примитивов на поверхности компонента (формы или области вывода иллюстрации) осуществляется применением соответствующих методов к свойству Canvas этого компонента.

Линия


Вычерчивание прямой линии осуществляет метод LinеТо, инструкция вызова которого в общем виде выглядит следующим образом:
Компонент.Canvas.LineTo(x,у)
Метод LinеТо вычерчивает прямую линию от текущей позиции карандаша в точку с координатами, указанными при вызове метода.
Начальную точку линии можно задать, переместив карандаш в нужную точку графической поверхности. Сделать это можно при помощи метода MoveTo, указав в качестве параметров координаты нового положения карандаша.
Вид линии (цвет, толщина и стиль) определяется значениями свойств объекта Реп графической поверхности, на которой вычерчивается линия.
Довольно часто результаты расчетов удобно представить в виде графика. Для большей информативности и наглядности графики изображают на фоне координатных осей и оцифрованной сетки. В листинге 10.2 приведен текст программы, которая на поверхность формы выводит координатные оси и оцифрованную сетку (10.4. Форма приложения Координатная сетка
Листинг 10.2. Оси координат и оцифрованная сетка
unit grid_;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
procedure FormPaint(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1; implementation
{$R *.DFM}
procedure TForm1.FormPaint(Sender: TObject);
var
x0,y0:integer; // координаты начала координатных осей
dx,dy:integer; // шаг координатной сетки (в пикселах)
h,w:integer; // высота и ширина области вывода координатной сетки
х,у:integer;
lx,ly:real; // метки (оцифровка) линий сетки по X и Y
dlx,dly:real; // шаг меток (оцифровки) линий сетки по X и Y
cross:integer; // счетчик неоцифрованных линий сетки
dcross:integer;// количество неоцифрованных линий между оцифрованными
begin
х0:=30; у0:=220; // оси начинаются в точке (40,250)
dx:=40; dy:=40; // шар координатной сетки 40 пикселов
dcross:=1; // помечать линии сетки X: 1 — каждую;
// 2 — через одну;
// 3 — через две;
dlx:=0.5; // шаг меток оси X
dly:=1.0; // шаг меток оси Y, метками будут: 1, 2, 3 и т. д.
h:=200; w:=300;
with forml.Canvas do begin
cross:=dcross;
MoveTo(x0,v0); LineTo(x0,y0-h); // ось X
MoveTo(x0,y0); LineTo(x0+w, y0); // ось Y
// засечки, сетка и оцифровка по оси X
x:=x0+dx;
lx:=dlx;
repeat
MoveTo(x,y0-3);LineTo(x,yO+3); // засечка
cross:=cross-l;
if cross = 0 then // оцифровка
begin
TextOut(x-8,y0+5,FloatToStr(lx));
cross:=dcross ; end;
Pen.Style:=psDot;
MoveTo(x,y0-3);LineTo(x,y0-h); // линия сетки
Pen.Style:=psSolid;
lx:=lx+dlx;
x:=x+dx;
until (x>x0+w);
// засечки, сетка и оцифровка по оси Y
y:=y0-dy;
ly:=dly;
repeat
MoveTo(х0-3,у);LineTo(х0+3,у); // засечка
TextOut(х0-20,у,FloatToStr(1у)); // оцифровка
Pen.Style:=psDot;
MoveTo(х0+3,у); LineTo(x0+w,у); // линия сетки
Pen.Style:=psSolid;
y:=y-dy;
ly:=ly+dly; until (y<y0-h);
end;
end;
end.
Особенность приведенной программы заключается в том, что она позволяет задавать шаг сетки и оцифровку. Кроме того, программа дает возможность оцифровывать не каждую линию сетки оси х, а через одну, две, три и т. д. Сделано это для того, чтобы предотвратить возможные наложения изображений чисел оцифровки друг на друга в случае, если эти числа состоят из нескольких цифр.

Ломаная линия


Метод polyline вычерчивает ломаную линию. В качестве параметра метод получает массив типа TPoint. Каждый элемент массива представляет собой запись, поля х и у которой содержат координаты точки перегиба ломаной. Метод Polyline вычерчивает ломаную линию, последовательно соединяя прямыми точки, координаты которых находятся в массиве: первую со второй, вторую с третьей, третью с четвертой и т. д.
В качестве примера использования метода Polyline в листинге 10.3 приведена процедура, которая выводит график изменения некоторой величины. Предполагается, что исходные данные находятся в доступном процедуре массиве Data (тип Integer).
Листинг 10.3. График функции (использование метода Polyline)
procedure TForml.Button1Click(Sender: TObject);
var
gr: array[1..50] of TPoint; // график — ломаная линия
x0,y0: integer; // координаты точки начала координат
dx,dy: integer; // шаг координатной сетки по осям X и Y
i: integer; begin
х0 := 10; у0 := 200; dx :=5; dy := 5;
// заполним массив gr
for i:=l to 50 do begin
gr[i].x := x0 + (i-l)*dx;
gr[i].y := y0 - Data[i]*dy;
end;
// строим график
with forml.Canvas do begin
MoveTo(x0,y0); LineTo(x0,10); // ось Y
MoveTo(x0,y0); LineTo(200,y0); // ось X
Polyline(gr); // график
end;
end;
Метод Polyline можно использовать для вычерчивания замкнутых контуров. Для этого надо, чтобы первый и последний элементы массива содержали координаты одной и той же точки. В качестве примера использования метода Polybine для вычерчивания замкнутого контура в листинге 10.4 приведена программа, которая на поверхности диалогового окна, в точке нажатия кнопки мыши, вычерчивает контур пятиконечной звезды (Цвет, которым вычерчивается звезда, зависит от того, какая из кнопок мыши была нажата. Процедура обработки нажатия кнопки мыши (событие MouseDown) вызывает процедуру рисования звезды starLine и передает ей в качестве параметра координаты точки, в которой была нажата кнопка. Звезду вычерчивает процедура starLine, которая в качестве параметров получает координаты центра звезды и холст, на котором звезда должна быть выведена. Сначала вычисляются координаты концов и впадин звезды, которые записываются в массив р. Затем этот массив передается в качестве параметра методу Polyline. При вычислении координат лучей и впадин звезды используются функции sin и cos. Так как аргумент этих функций должен быть выражен в радианах, то значение угла в градусах домножается на величину pi/18о, где pi — это стандартная именованная константа равная числу л.
Листинг 10.4. Вычерчивание замкнутого контура (звезды) в точке нажатия кнопки мыши
unit Stars_; interface
uses
Windows, Messages, SysUtils, Variants, Classes,
Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Forml: TForml;
implementation
f$R *.dfm}
// вычерчивает звезду
procedure StarLine(x0,y0,r: integer; Canvas: TCanvas);
// x0,y0 — координаты центра звезды
//r — радиус заезды var
р : array [1.. 11] of TPoint;
// массив координат лучей и впадин
a: integer; // угол между осью ОХ и прямой, соединяющей
// центр звезды и конец луча или впадину i: integer;
begin
а := 18; // строим от правого гор. луча
for i:=l to 10 do begin
if (i mod 2=0) then begin // впадина
p[i].x := x0+Round(r/2*cos(a*pi/180) ) ;
p[i] .y:=y0-Round(r/2*sin(a*pi/180) ) ;
end
else
begin // луч
[i] .x:=x0+Round(r*cos (a*pi/180) ) ;
[i] .y:=y0-Round(r*sin(a*pi/180) ) ;
end;
a := a+36;
end;
p[ll].X := p[l].X; // чтобы замкнуть контур звезды
Canvas. Polyline (р) ; // начертить звезду
end;
// нажатие кнопки мыши
procedure TForm1 . FormMouseDown { Sender : TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft // нажата левая кнопка?
then Form1. Canvas . Pen . Color : = clRed
else Form1. Canvas. Pen. Color := clGreen;
StarLine(x, y, 30, Forml. Canvas );
end;
end.
Примечание
Обратите внимание, что размер массива р на единицу больше, чем количество концов и впадин звезды, и что значения первого и последнего элементов массива совпадают.

Окружность и эллипс


Метод Ellipse вычерчивает эллипс или окружность, в зависимости от значений параметров. Инструкция вызова метода в общем виде выглядит следующим образом:
Объект.Canvas.Ellipse(x1,y1, х2,у2]
где:

  • объект — имя объекта (компонента), на поверхности которого выполняется вычерчивание;

x1, y1, х2, у2 — координаты прямоугольника, внутри которого вычерчивается эллипс или, если прямоугольник является квадратом, окружность (10.6. Значения параметров метода Ellipse определяют вид геометрической фигуры
Цвет, толщина и стиль линии эллипса определяются значениями свойства Реп, а цвет и стиль заливки области внутри эллипса — значениями свойства Brush поверхности (canvas), на которую выполняется вывод.

Дуга


Вычерчивание дуги выполняет метод Arc, инструкция вызова которого в общем виде выглядит следующим образом:
Объект.Canvas.Arc(x1,y1,х2,у2,х3,у3,х4,у4)
где:

  • x1, y1, х2, у2 — параметры, определяющие эллипс (окружность), частью которого является вычерчиваемая дуга;
  • х3, у3 — параметры, определяющие начальную точку дуги; П х4, у4 — параметры, определяющие конечную точку дуги.

Начальная (конечная) точка — это точка пересечения границы эллипса и прямой, проведенной из центра эллипса в точку с координатами х3 и у3 (х4, у4). Дуга вычерчивается против часовой стрелки от начальной точки к конечной (толщина и стиль линии, которой вычерчивается дуга, определяются значениями свойства Реп поверхности (canvas), на которую выполняется вывод.
Прямоугольник
Прямоугольник вычерчивается методом Rectangle, инструкция вызова которого в общем виде выглядит следующим образом:
Объект.Canvas.Rectangle(x1, y1,x2, y2)
где:

  • объект — имя объекта (компонента), на поверхности которого выполняется вычерчивание;
  • x1, y1 и х2, у2 — координаты левого верхнего и правого нижнего углов прямоугольника.

Метод RoundRec тоже вычерчивает прямоугольник, но со скругленными углами. Инструкция вызова метода RoundRec выглядит так:
Объект.Canvas.RoundRec(x1,y1,х2, у2, х3, у3)
где:

  • x1, y1, х2, у2 -- параметры, определяющие положение углов прямоугольника, в который вписывается прямоугольник со скругленными углами;

х3 и у3 — размер эллипса, одна четверть которого используется для вычерчивания скругленного угла (10.8. Метод RoundRec вычерчивает прямоугольник со скругленными углами
Вид линии контура (цвет, ширина и стиль) определяется значениями свойства Реп, а цвет и стиль заливки области внутри прямоугольника — значениями свойства Brush поверхности (canvas), на которой прямоугольник вычерчивается.
Есть еще два метода, которые вычерчивают прямоугольник, используя в качестве инструмента только кисть (Brush). Метод FillRect вычерчивает закрашенный прямоугольник, а метод FrameRect — только контур. У каждого из этих методов лишь один параметр — структура типа TRect. Поля структуры TRect содержат координаты прямоугольной области, они могут быть заполнены при помощи функции Rect.
Ниже в качестве примера использования методов FillRect и FrameRect приведена процедура, которая на поверхности формы вычерчивает прямоугольник с красной заливкой и прямоугольник с зеленым контуром.
procedure TForm1.Button1Click(Sender: TObject);
var
r1, r2: TRect; // координаты углов прямоугольников
begin
// заполнение полей структуры
// зададим координаты углов прямоугольников
r1 := Rect(20,20,60,40);
r2 := Rect(10,10,40,50);
with fоrm1.Canvas do begin
Brush.Color := clRed;
FillRect(r1); // закрашенный прямоугольник
Brush.Color := clGreen;
FrameRect(r2}; // только граница прямоугольника
end;
end;
Многоугольник
Метод Polygon вычерчивает многоугольник. В качестве параметра метод получает массив типа TPoint. Каждый элемент массива представляет собой запись, поля (х,у) которой содержат координаты одной вершины многоугольника. Метод Polygon вычерчивает многоугольник, последовательно соединяя прямыми линиями точки, координаты которых находятся в массиве: первую со второй, вторую с третьей, третью с четвертой и т. д. Затем соединяются последняя и первая точки.
Цвет и стиль границы многоугольника определяются значениями свойства Реп, а цвет и стиль заливки области, ограниченной линией границы, — значениями свойства Brush, причем область закрашивается с использованием текущего цвета и стиля кисти.
Ниже приведена процедура, которая, используя метод polygon, вычерчивает треугольник:
procedure TForm1.Button2Click(Sender: TObject);
var
pol: array[1..3] of TPoint; // координаты точек треугольника
begin
pol[1].x := 10;
polf1].y := 50;
pol[2].x := 40;
pol[2].y := 10;
pol[3].х := 70;
pol[3].у := 50;
Form1.Canvas.Polygon(pol);
end;

Сектор


Метод pie вычерчивает сектор эллипса или круга. Инструкция вызова метода в общем виде выглядит следующим образом:
Объект. Canvas.Pie(x1,y1,x2,y2,х3,у3,х4,у4)
где:

  • x1, y1, х2, у2 — параметры, определяющие эллипс (окружность), частью которого является сектор;
  • х3, у3, х4, у4 — параметры, определяющие координаты конечных точек прямых, являющихся границами сектора.

Начальные точки прямых совпадают с центром эллипса (окружности). Сектор вырезается против часовой стрелки от прямой, заданной точкой с координатами (хЗ, уз), к прямой, заданной точкой с координатами (х4, у4) (10.9. Значения параметров метода Pie определяют сектор как часть эллипса (окружности)

Точка


Поверхности, на которую программа может осуществлять вывод графики, соответствует объект Canvas. Свойство pixels, представляющее собой двумерный массив типа TColor, содержит информацию о цвете каждой точки графической поверхности. Используя свойство Pixels, можно задать тре-
буемый цвет для любой точки графической поверхности, т. е. "нарисовать" точку. Например, инструкция
Form1.Canvas.Pixels[10,10]:=clRed
окрашивает точку поверхности формы в красный цвет.
Размерность массива pixels определяется размером графической поверхности. Размер графической поверхности формы (рабочей области, которую также называют клиентской) задается значениями свойств ciientwidth и ClientHeight, а размер графической поверхности компонента image — значениями свойств width и Height. Левой верхней точке рабочей области формы соответствует элемент pixels [0,0], а правой нижней -Pixels[Ciientwidth - 1,ClientHeight - 1].
Свойство Pixels можно использовать для построения графиков. График строится, как правило, на основе вычислений по формуле. Границы диапазона изменения аргумента функции являются исходными данными. Диапазон изменения значения функции может быть вычислен. На основании этих данных можно вычислить масштаб, позволяющий построить график таким образом, чтобы он занимал всю область формы, предназначенную для вывода графика.
Например, если некоторая функция f(x) может принимать значения от нуля до 1000, и для вывода ее графика используется область формы высотой в 250 пикселов, то масштаб оси Y вычисляется по формуле: т = 250/1000. Таким образом, значению f(x) = 70 будет соответствовать точка с координатой Y =233. Значение координаты Y вычислено по формуле
Y= h -f(x) х т = 250 - 70х(250/1000),
где h - высота области построения графика.
Обратите внимание на то, что точное значение выражения 250 - 70х(250/1000) равно 232,5. Но т. к. индексом свойства pixels, которое используется для вывода точки на поверхность Canvas, может быть только целое значение, то число 232,5 округляется к ближайшему целому, которым является число 233.
Следующая программа, текст которой приведен в листинге 10.5, используя свойство pixels, выводит график функции у = 2 sin(jc) e*/5. Для построения графика используется вся доступная область формы, причем если во время работы программы пользователь изменит размер окна, то график будет выведен заново с учетом реальных размеров окна.
Листинг 10.5. График функции
unit grfunc_;
interface
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs;
type
TForm1 = class(TForm)
procedure FormPaint(Sender: TObject);
procedure FormResize(Sender: TObject);
private
{ Private declarations }
public
{Public declarations }
end;
var
Forml: TForml;
implementation
{$R *.DFM}
// Функция, график которой надо построить
Function f(x:real):real;
begin
f:=2*Sin(x)*exp(x/5) ;
end;
// строит график функции
procedure GrOfFunc;
var
x1,x2:real; // границы изменения аргумента функции
y1,y2:real; // границы изменения значения функции
х:real; // аргумент функции
у:real; // значение функции в точке х
dx:real; // приращение аргумента
l,b:integer; // левый нижний угол области вывода графика
w,h:integer; // ширина и высота области вывода графика
mx,my:real; // масштаб по осям X и Y
х0,у0:integer; // точка — начало координат
begin
// область вывода графика
l:=10; // X — координата левого верхнего угла
b:=Forml.ClientHeight-20;
//У — координата левого верхнего угла
h:=Forml.ClientHeight-40; // высота
w:=Forml.Width-40; // ширина
x1:=0; // нижняя граница диапазона аргумента
х2:=25; // верхняя граница диапазона аргумента
dx:=0.01; // шаг аргумента
// найдем максимальное и минимальное значения
// функции на отрезке [x1,x2]
y1:=f(xl); // минимум
y2:=f(xl); //максимум
x:=x1;
repeat
У := f (х);
if у < yl then yl:=y;
if у > у2 then y2:=y;
х:=x+dx; until (x >= х2);
// вычислим масштаб
my:=h/abs(y2-yl); // масштаб по оси Y
mx:=w/abs(x2-xl); // масштаб по оси X
х0:=1;
у0:=b-Abs(Round(y1*my)) ;
with form1.Canvas do
begin
// оси
MoveTo(l,b);LineTo(l,b-h);
MoveTo(x0,y0);LineTo(x0+w,y0);
TextOut(l+5,b-h,FloatToStrF(y2,ffGeneral,6,3));
TextOut(l+5,b,FloatToStrF(yl,ffGeneral,6,3));
// построение графика
x:=xl; repeat
y:=f(x);
Pixels[x0+Round(x*mx),y0-Round(y*my)]:=clRed;
x:=x+dx;
until (x >= x2);
end;
end;
procedure TForm1.FormPaint(Sender: TObject);
begin
GrOfFunc; end;
// изменился размер окна программы
procedure TForm1.FormResize(Sender: TObject);
begin
// очистить форму
forml.Canvas.FillRect(Rect(0,0,ClientWidth,
ClientHeight));
// построить график
GrOfFunc;
end;
end.

Основную работу выполняет процедура GrOfFunc, которая сначала вычисляет максимальное (у2) и минимальное (yl) значения функции на отрезке [x1l,x2]. Затем, используя информацию о ширине (Forml.Clientwidth -40) и высоте (Form1.ClientHeight - 40) области вывода графика, вычисляет масштаб по осям X (mх) иY(mу).
Высота и ширина области вывода графика определяется размерами рабочей (клиентской) области формы, т. е. без учета области заголовка и границ. После вычисления масштаба процедура вычисляет координату у горизонтальной оси (уо) и вычерчивает координатные оси графика. Затем выполняется непосредственное построение графика (процедуры GrOfFunc выполняют процедуры обработки событий onPaint и onFormResize. Процедура TForm1. FormPaint обеспечивает вычерчивание графика после появления формы на экране в результате запуска программы, а также после появления формы во время работы программы, например, в результате удаления или перемещения других окон, полностью или частично перекрывающих окно программы. Процедура TForm1.FormResize обеспечивает вычерчивание графика после изменения размера формы.
Приведенная программа довольно универсальна. Заменив инструкции в теле функции f (х), можно получить график другой функции. Причем независимо от вида функции ее график будет занимать всю область, предназначенную для вывода.
Примечание
Рассмотренная программа работает корректно, если функция, график которой надо построить, принимает как положительные, так и отрицательные значения. Если функция во всем диапазоне только положительная или только отрицательная, то в программу следует внести изменения. Какие — пусть это будет упражнением для читателя.

Вывод иллюстраций


Наиболее просто вывести иллюстрацию, которая находится в файле с расширением bmp, jpg или ico, можно при помощи компонента image, значок которого находится на вкладке Additional палитры (10.11. Значок компонента Image
В табл. 10.8 перечислены основные свойства компонента image.
Таблица 10.8. Свойства компонента image

Иллюстрацию, которая будет выведена в поле компонента image, можно задать как во время разработки формы приложения, так и во время работы программы.
Во время разработки формы иллюстрация задается установкой значения свойства picture путем выбора файла иллюстрации в стандартном диалоговом окне, которое появляется в результате щелчка на командной кнопке Load окна Picture Editor (Чтобы запустить Image Editor, нужно в окне Object Inspector выбрать свойство Picture и щелкнуть на кнопке с тремя точками.
Если размер иллюстрации больше размера компонента, то свойству strech нужно присвоить значение True и установить значения свойств width и Height пропорционально реальным размерам иллюстрации.
Чтобы вывести иллюстрацию в поле компонента image во время работы программы, нужно применить метод LoadFromFile к свойству Picture, указав в качестве параметра имя файла иллюстрации. Например, инструкция
Form1.Image1.Picture.LoadFromFile('e:\temp\bart.bmp')
загружает иллюстрацию из файла bart.bmp и выводит ее в поле вывода иллюстрации (imagel).
Метод LoadFromFile позволяет отображать иллюстрации различных графических форматов: BMP, WMF, JPEG (файлы с расширением jpg).
Следующая программа, ее текст приведен в листинге 10.6, использует компонент image для просмотра иллюстраций, которые находятся в указанном пользователем каталоге. Диалоговое окно программы приведено на 10.12. Окно Picture Editor
Листинг 10.6. Слайд-проектор
unit shpic_;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, Menu
type
TForm1 = class(TForm) Image1: ТImage;
Button1: TButton;
procedure FormActivate(Sender: TObject);
procedure ButtonlClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
aSearchRec : TSearchRec;
aPath : String; // каталог, в котором находятся иллюстрации
aFile : String; // файл иллюстрации
iw,ih: integer; // первоначальный размер компонента Image
implementation
$R *.DFM}
// изменение размера области вывода иллюстрации
// пропорционально размеру иллюстрации
Procedure Scalelmage;
var
pw, ph : integer; // размер иллюстрации
scaleX, scaleY : real; // масштаб по Х и Y
scale : real; // общий масштаб
begin
// иллюстрация уже загружена
// получим ее размеры
pw := Form1.Image1.Picture.Width;
ph := Form1.Image1.Picture.Height;
if pw > iw // ширина иллюстрации больше ширины компонента Image
then scaleX := iw/pw // нужно масштабировать
else scaleX := 1;
if ph > ih // высота иллюстрации больше высоты компонента
then scaleY := ih/ph // нужно масштабировать
else scaleY := 1;
// выберем наименьший коэффициент
if scaleX < scaleY
then scale := scaleX
else scale := scaleY;
// изменим размер области вывода иллюстрации
Form1.Image1.Height := Round(Form1.Image1.Picture.Height*scale)
Form1.Image1.Width := Round(Form1.Image1.Picture.Width*scale);
// т. к. Strech = True и размер области пропорционален
// размеру картинки, то картинка масштабируется без искажений
end;
// вывести первую иллюстрацию
procedure FirstPicture;
var
r : integer; // результат поиска файла
begin
aPath := 'f:\temp\';
r := FindFirst(aPath+'*.bmp',faAnyFile,aSearchRec);
if г = 0 then
begin // в указанном каталоге есть bmp-файл
aFile := aPath + aSearchRec.Name;
Form1.Image1.Picture.LoadFromFile(aFile); // загрузить
// иллюстрацию
Scalelmage; //-установить размер компонента
Image r := FindNext(aSearchRec); // найти следующий файл
if r = 0 then // еще есть файлы иллюстраций
Forml.Button1.Enabled := True;
end;
end;
// вывести следующую иллюстрацию
Procedure NextPicture();
var
r : integer;
begin
aFile := aPath + aSearchRec.Name;
Forml.Image1.Picture.LoadFromFile(aFile);
Scalelmage;
// подготовим вывод следующей иллюстрации
r := FindNext(aSearchRec); // найти следующий файл
if r<>0
then // больше нет иллюстраций
Forml.Buttonl.Enabled := False;
end;
procedure TForml.FormActivate(Sender: TObject);
begin
Image1.AutoSize := False; // запрет автоизменения размера компонента
Image1.Stretch := True; // разрешим масштабирование
// запомним первоначальный размер области вывода иллюстрации
iw := Imagel.Width;
in := imagel.Height;
Button1.Enabled := False; // сделаем недоступной кнопку Дальше
FirstPicture; // вывести первую иллюстрацию
end;
//щелчок на кнопке Дальше
procedure TForm1.Button1Click(Sender: TObject);
begin
NextPicture;
end;
end.
Программа выполняет масштабирование выводимых иллюстраций без искажения, чего нельзя добиться простым присвоением значения True свойству strech. Загрузку и вывод первой и остальных иллюстраций выполняют соответственно процедуры FirstPicture и NextPicture. Процедура FrirstPicture использует функцию FindFirst для того, чтобы получить имя первого BMP-файла. В качестве параметров функции FindFirst передаются:

  • имя каталога, в котором должны находиться иллюстрации;
  • структура asearchRec, поле Name которой, в случае успеха, будет содержать имя файла, удовлетворяющего критерию поиска;
  • маска файла иллюстрации.

Если в указанном при вызове функции FindFirst каталоге есть хотя бы один BMP-файл, значение функции будет равно нулю. В этом случае метод LoadFromFiie загружает файл иллюстрации, после чего вызывается функция scaieimage, которая устанавливает размер компонента пропорционально размеру иллюстрации. Размер загруженной иллюстрации можно получить, обратившись к свойствам Form1.Image1.Picture.Width и Form1.Шmage1.Picture.Height, значения которых не зависят от размера компонента Image.

Битовые образы


При работе с графикой удобно использовать объекты типа TBitMap (битовый образ). Битовый образ представляет собой находящуюся в памяти компьютера, и, следовательно, невидимую графическую поверхность, на которой программа может сформировать изображение. Содержимое битового образа (картинка) легко и, что особенно важно, быстро может быть выведено на поверхность формы или области вывода иллюстрации (image). Поэтому в программах битовые образы обычно используются для хранения небольших изображений, например, картинок командных кнопок.
Загрузить в битовый образ нужную картинку можно при помощи метода LoadFromFlie, указав в качестве параметра имя BMP-файла, в котором находится нужная иллюстрация.
Например, если в программе объявлена переменная pic типа TBitMap, то после выполнения инструкции
pic.LoadFromFiie('е:\images\aplane.bmp')
битовый образ pic будет содержать изображение самолета.
Вывести содержимое битового образа (картинку) на поверхность формы или области вывода иллюстрации можно путем применения метода Draw к соответствующему свойству поверхности (canvas). Например, инструкция
Image1.Canvas.Draw(x,у, bm)
выводит картинку битового образа bm на поверхность компонента image 1 (параметры х и у определяют положение левого верхнего угла картинки на поверхности компонента).
Если перед применением метода Draw свойству Transparent объекта TBitMap присвоить значение True, то фрагменты рисунка, окрашенные цветом, совпадающим с цветом левого нижнего угла картинки, не будут выве-
дены — через них будет как бы проглядывать фон. Если в качестве "прозрачного" нужно использовать цвет, отличный от цвета левой нижней точки рисунка, то свойству Transparentcoior следует присвоить значение символьной константы, обозначающей необходимый цвет.
Следующая программа, текст которой приведен в листинге 10.7, демонстрирует использование битовых образов для формирования изображения из нескольких элементов.
Листинг 10.7. Использование битовых образов
unit aplanes_; interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs;
type
TForml = class(TForm)
procedure FormPaint(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Forml: TForm1;
sky,aplane: TBitMap; // битовые образы: небо и самолет
implementation
($R *.DFM}
procedure TForm1.FormPaint(Sender: TObject);
begin
// создать битовые образы
sky := TBitMap.Create;
aplane := TBitMap.Create;
// загрузить картинки
sky.LoadFromFile('sky.bmp');
aplane.LoadFromFile('aplane.bmp') ;
Form1.Canvas.Draw(0,0,sky); // отрисовка фона
Form1.Canvas.Draw(20,20,aplane); // отрисовка левого самолета
aplane.Transparent:=True;
// теперь элементы рисунка, цвет которых совпадает с цветом
// левой нижней точки битового образа, не отрисовываются Form1.Canvas.Draw(120,20,aplane);
// отрисовка правого самолета
// освободить память sky.free; aplane.free;
end;
end.
После запуска программы в окне приложения (появляется изображение летящих на фоне неба самолетов. Фон и изображение самолета -битовые образы, загружаемые из файлов. Белое поле вокруг левого самолета показывает истинный размер картинки битового образа aplane. Белое поле вокруг правого самолета отсутствует, т. к. перед его выводом свойству Transparent битового образа было присвоено значение True.

 

 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г. Яндекс.Метрика